回答

收藏

等效窗口句子LISTAGG

技术问答 技术问答 205 人阅读 | 0 人回复 | 2023-09-14

在oracle中,该LISTAGG函数允许我将其与OVER (PARTITION BYcolumn..)一起使用子句。但是,它不支持使用带有ROWS或RANGE关键字窗口。
" F0 r- g3 F/ z- S" \7 u我有一个来自商店寄存器的数据集(简化了这个问题)。请注意,寄存器表的数量总是1-一个,一个交易行。
0 U3 E% @; f/ D1 v6 MTranID TranLine ItemId OrderID Dollars Quantity------ -------- ------ ------- ------- --------   101         238455 233      23      .99   11     102     23845 23845 23     23        22.99    11      103      23845  23      2.99   11      104     23845  2335     23       22.99   11      105      23845  2335     23       22.99    1我必须将这些数据匹配到特殊订购系统中的表中。在这个系统中,项目按数量分组。请注意,该系统可以在多行中拥有相同的项目ID(即使项目相同,订购的组件也可能不同)。
5 B. ~" }) F- XItemId OrderID Order Line Dollars Quantity------ ------- ---------- ------- --------23845  233          88        8885             88885          .323845  2333            55           555                                 5555.98    2我可以匹配这个数据 唯一    方法是按订单ID,商品ID匹配美元金额。$ k# q9 N  Y+ i: f3 H
本质上,我需要得到以下结果。
" N# d3 U$ r7 P1 EItemId OrderID Order Line Dollars Quantity Tran ID  Tran Lines------ ------- ---------- ------- -------- -------  ----------23845  233          88        8885             88885          .102;10323845  23                                     555.105    我不太在意tran我只关心美元金额是否匹配,我在计算特殊订单总数时不会重用寄存器中的一行。我不需要tran行分解成表-. w' z3 d$ e/ n- `
这是为了报告,粒度永远不会降低到寄存器事务行的水平。7 D  n' B9 h; n6 O8 V" u
我最初的想法是,我可以使用分析函数来实现最佳匹配,以识别与订单系统中的美元数量和数量相匹配的第一行,以获得以下结果集:
. M' k+ \0 F5 QTranID TranLine ItemId OrderID Dollars Quantity CumDollar  CumQty------ -------- ------ ------- ------- -------- --------   ------   101         238455 233      23      .99   1        2.99      11     102  238845  23845    23     23     .99   1     555            555                555555                             555555                                     555555555                      555555                           5555555555555555555                                     55555555555555555                                    55555555555555555555555                              55555555555555555555555                                                                    5555555555555555555555                                                                                                                                          .88      21      103  23845   23845     23        22.99   1     88    88    88     888           888.97      31      104  23845  23845    23     23        22. 11111    .1055  23845  235       2385      23        22.99  1       144.95      5到目前为止,一切都很好。但是,然后我试着LISTAGG添加到我的查询中:
+ B+ `# d, ]- [" ]: xSELECT 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:
( n8 ^. K* A7 {: OTranID TranLine ItemId OrderID Dollars Quantity CumDollar  CumQty ListAgg------ -------- ------ ------- ------- -------- --------   ------ -------   101         238455 233      23      .99   1        2.102;103;104;1051;1051;1051;102,102,102,102,1051,102,102,23845,23102,102、102、102、102、23845、23、23、23、23.99    1        5.102;103;104;1051;1051;1051103,1051,103,103,103,103,103,103,103,103,103,103,103,103,23845,23,23,23.99   1     88    88    88     888           888.102;103;104;1051;1051;1051;104;10511051;104;104   23845  23         235. 11111    .102;103;104;1051;1051;1051;105;105;105;105;105;105;     23845.99  1       144.102;103;104;105所以,这没用。2 L- C1 s& {0 u% l  p: n
如果可能的话,我更愿意在SQL执行此操作。我知道我可以用游标和过程逻辑来做到这一点。
( T. A+ R; c$ Y( l0 i: u, d1 h用什么方法?LISTAGG窗口化的分析功能,还是可以使用其他支持该功能的分析功能?/ x! [& J# U4 P+ @& g! }
我正在使用11gR2。% |5 W- j' A4 Y" u1 u5 q; N% y& X; b
                                                                8 B2 n4 h' W, D  H( e' r* ~
    解决方案:                                                               
* X: g& p# L- Y                                                                唯一能想到的方法就是用相关子查询:1 y9 C, V3 W2 [5 t* m
WITH CTE AS(   SELECT  TranID,            TranLine,            ItemID,            OrderID,            Dollars,            Quantity,            SUM(dollars) OVER (PARTITION BY TranID,ItemID,OrderID ORDER BY TranLine) AS CumDollar,            SUM(Quantity) OVER (PARTITION BY TranID,ItemID,OrderID ORDER BY TranLine) AS CumQuantity    FROM    T)SELECT  TranID,        TranLine,        ItemID,        OrderID,                                Dollars,        Quantity,        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,itemid,orderid       AS ListAggFROM    CTE T1;我意识到这不能提供你需要的确切输出,但我希望它足以克服积累LISTAGG问题并帮你一臂之力。" ]9 G9 X# t, u/ ?' y  A
我已经设置了一个SQL Fiddle演示解决方案。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则