【发布时间】:2012-06-08 16:50:55
【问题描述】:
在 oracle 中,LISTAGG 函数允许我通过 OVER (PARTITION BY column..) 子句进行分析使用。但是,它不支持使用带有 ROWS 或 RANGE 关键字的窗口。
我有一个来自存储寄存器的数据集(针对问题进行了简化)。请注意,注册表的数量始终为 1 - 一项,一项交易行。
TranID TranLine ItemId OrderID Dollars Quantity
------ -------- ------ ------- ------- --------
1 101 23845 23 2.99 1
1 102 23845 23 2.99 1
1 103 23845 23 2.99 1
1 104 23845 23 2.99 1
1 105 23845 23 2.99 1
我必须将此数据“匹配”到特殊订单系统中的表格,其中项目按数量分组。请注意,系统可以在多行上具有相同的商品 ID(即使商品相同,订购的组件也可能不同)。
ItemId OrderID Order Line Dollars Quantity
------ ------- ---------- ------- --------
23845 23 1 8.97 3
23845 23 2 5.98 2
唯一我可以匹配这些数据的方法是通过订单 ID、项目 ID 和美元金额。
基本上我需要得到以下结果。
ItemId OrderID Order Line Dollars Quantity Tran ID Tran Lines
------ ------- ---------- ------- -------- ------- ----------
23845 23 1 8.97 3 1 101;102;103
23845 23 2 5.98 2 1 104;105
我并不特别关心 tran 行是否以任何方式排序,我只关心美元金额是否匹配,并且我不会“重复使用”寄存器中的一行来计算总数特殊订单。我不需要将 tran 行拆分为表格 - 这是出于报告目的,并且粒度永远不会回到注册事务行级别。
我最初的想法是,我可以使用分析函数来执行此操作,以进行“最佳匹配”,以识别与订购系统中的美元金额和数量匹配的第一组行,给我一个结果集,如下所示:
TranID TranLine ItemId OrderID Dollars Quantity CumDollar CumQty
------ -------- ------ ------- ------- -------- -------- ------
1 101 23845 23 2.99 1 2.99 1
1 102 23845 23 2.99 1 5.98 2
1 103 23845 23 2.99 1 8.97 3
1 104 23845 23 2.99 1 11.96 4
1 105 23845 23 2.99 1 14.95 5
到目前为止一切顺利。但我随后尝试将 LISTAGG 添加到我的查询中:
SELECT tranid, tranline, itemid, orderid, dollars, quantity,
SUM(dollars) OVER (partition by tranid, itemid, orderid order by tranline) cumdollar,
SUM(quantity) OVER (partition by tranid, itemid, orderid order by tranline) cumqty
LISTAGG (tranline) within group (order by tranid, itemid, orderid, tranline) OVER (partition by tranid, itemid, orderid)
FROM table
我发现它总是返回一个完整的 agg 而不是累积的 agg:
TranID TranLine ItemId OrderID Dollars Quantity CumDollar CumQty ListAgg
------ -------- ------ ------- ------- -------- -------- ------ -------
1 101 23845 23 2.99 1 2.99 1 101;102;103;104;105
1 102 23845 23 2.99 1 5.98 2 101;102;103;104;105
1 103 23845 23 2.99 1 8.97 3 101;102;103;104;105
1 104 23845 23 2.99 1 11.96 4 101;102;103;104;105
1 105 23845 23 2.99 1 14.95 5 101;102;103;104;105
所以这没有用。
如果可能的话,我更愿意在 SQL 中执行此操作。我知道我可以用游标和程序逻辑来做到这一点。
有没有办法使用 LISTAGG 分析函数或其他支持此功能的分析函数进行窗口化?
我正在使用 11gR2。
【问题讨论】:
-
+1 表示写得非常有趣的问题。