Oracle中LISTAGG()函数简单应用

需求场景:

工作中经常遇到很多需求是这样的,根据某些条件汇总某些字段,此时使用Oracle中的LISTAGG()函数可以较为方便的解决问题。
之前在使用group by时基本都使用max、min、sum、count来使得结果归类,如果遇到无法使用上述函数做处理的数据结构,就傻眼了,就会只在数据库中拿取基础数据,然后再在代码中循环处理,直到我知道了LISTAGG()函数。

LISTAGG()使用条件:

(1). 必须得分组,也就是说group by是必须的。
(2). listagg函数的第一个参数是需要显示的字段,也就是log_name;第二个参数是数值之间的分隔符;同时还需要进行排序和分组within group (order by name)

下面为使用此函数解决的问题示例:
示例中用了" ; "作为分隔符来拼接所需字段,然后用instr()获取分隔符的下标index来和SUBSTR()的截取来做配合实现功能

SELECT
    SUBSTR(LISTAGG(RIDING_DATE,';') WITHIN GROUP ( ORDER BY ID ),-17,17) AS issueDate,
    PASSENGER_NAME AS passenger,
    MAX(CARD_NO) AS cardNo,
    SUBSTR(LISTAGG(BILL_NO,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(BILL_NO,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) AS ticketNumber,
    MAX(PRODUCT_ORDER_NO) AS productOrderNo,
    MAX(ACCEPT_CARRIAGE) AS carriage,
    SUBSTR(LISTAGG(TRAIN_NO,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(TRAIN_NO,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) AS trainNo,
    SUBSTR(LISTAGG(SEAT_CLASS_NAME,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(SEAT_CLASS_NAME,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) AS seatClassName,
    SUBSTR(LISTAGG(FROM_STATION,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(FROM_STATION,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) || '-' || SUBSTR(LISTAGG(TO_STATION,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(TO_STATION,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) AS journey,
    SUBSTR(LISTAGG(RIDING_DATE,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(RIDING_DATE,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) AS ridingDate,
    SUBSTR(LISTAGG(ARRIVAL_DATE,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(ARRIVAL_DATE,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) AS arrivalDate,
    SUBSTR(LISTAGG(SALE_PRICE,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(SALE_PRICE,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) AS ticketPrice,
    SUBSTR(LISTAGG(REFUND_FEE,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(REFUND_FEE,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) AS refundFee,
    SUM(SALE_RECEIVABLE) AS actuallyPay,
    SUBSTR(LISTAGG(ORDER_TYPE,';') WITHIN GROUP ( ORDER BY ID ),instr(LISTAGG(ORDER_TYPE,';') WITHIN GROUP ( ORDER BY ID ),';',-1)+1) AS ticketStatus,
    LISTAGG ( CASE ORDER_TYPE WHEN '0' THEN '出' WHEN '2' THEN '改' WHEN '5' THEN '退' END, '-' ) WITHIN GROUP ( ORDER BY ID ) AS remark,
    MAX(CLIENT_NAME) AS clientName
FROM
    T_TRAIN_SALE
<where>
    <if test="startDate != null and endDate != null">
        SETTLE_DATE BETWEEN #{startDate} AND #{endDate}
    </if>
    <if test="clientName != null">
        AND CLIENT_NAME LIKE '%' || #{clientName} || '%'
    </if>
</where>
GROUP BY
    PRODUCT_ORDER_NO,
    PASSENGER_NAME
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

'Boom'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值