sql – LISTAGG等效于windowing子句

前端之家收集整理的这篇文章主要介绍了sql – LISTAGG等效于windowing子句前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在oracle中,LISTAGG函数允许我用OVER(PARTITION BY column ..)子句分析地使用它.但是,它不支持使用ROWS或RANGE关键字使用窗口.

我有一个来自商店寄存器的数据集(简化了问题).请注意,寄存器表的数量始终为1 – 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

我不是特别关心转换线是否以任何方式进行订购,所有我关心的是美元数量相匹配,而且我不会在注册表中“重新使用”一行来计算特定订单的总额.我不需要将转换分解成一个表 – 这是为了报告的目的,粒度永远不会回到注册事务线级别.

我的初步想法是,我可以通过分析功能来做到这一点,做一个“最佳匹配”,以确定与订单系统中的美元数量数量相匹配的第一组行,给出如下结果:

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,orderid order by tranline) cumdollar,SUM(quantity) OVER (partition by tranid,orderid order by tranline) cumqty
       LISTAGG (tranline) within group (order by tranid,tranline) OVER (partition by tranid,orderid)
FROM table

我发现它总是返回一个完整的,而不是一个累积的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.

解决方法

我可以想到的唯一方法就是使用相关的子查询
WITH CTE AS
(   SELECT  TranID,TranLine,ItemID,OrderID,Dollars,Quantity,SUM(dollars) OVER (PARTITION BY TranID,OrderID ORDER BY TranLine) AS CumDollar,SUM(Quantity) OVER (PARTITION BY TranID,OrderID ORDER BY TranLine) AS CumQuantity
    FROM    T
)
SELECT  TranID,CumDollar,CumQuantity,(   SELECT  LISTAGG(Tranline,';') WITHIN GROUP(ORDER BY CumQuantity)
            FROM    CTE T2
            WHERE   T1.CumQuantity >= T2.CumQuantity
            AND     T1.ItemID = T2.ItemID
            AND     T1.OrderID = T2.OrderID
            AND     T1.TranID = T2.TranID
            GROUP BY tranid,orderid
        ) AS ListAgg
FROM    CTE T1;

我意识到这并没有给出您要求的确切输出,但希望足以克服累积LISTAGG的问题并让您顺利进行.

我已经设置了一个SQL Fiddle来演示解决方案.

原文链接:https://www.f2er.com/mssql/76176.html

猜你在找的MsSQL相关文章