连接两个分组子查询 IBM i、DB2 SQL

Joining two grouped subqueries IBM i, DB2 SQL

下午好,

我正在尝试创建一个每日销售报告摘要,加入几个不同的文件并根据不同的因素进行总结。

报告将以如下形式结束:

Category    On Hold    Back Orders    Late    Current Month    Next Month    Future Months    Total
LOC          24.75        50.01       15.00      45.00           25.25           28.03        188.04            
MAR          16.15        21.85       31.20      18.00           25.00           34.05        146.25
....

各种会计 类。我正在使用 DB2 SQL 从 AS400、IBM I 服务器中提取数据。

我可以独立总结一些类别,但很难将它们组合在一起。例如等待:

SELECT x.CDA0CD, SUM(x.CDDUVA) AS "On Hold"     
  FROM (
     SELECT LINES.CDCVNB, /* QUOTE/ORDER NO */
            LINES.CDDCCD, /* ORDER TYPE */
            LINES.CDAITX, /* ITEM NUMBER */ 
            LINES.CDGLCD, /* ITEM CLASS */
            LINES.CDA0CD, /* IAC */
            LINES.CDDUVA, /* LC - NET SALES AMOUNT */
            HOLDS.CKCZCD, /* HOLD CODE */
            HOLDS.CKACP8, /* RELEASE TYPE */            
            LINES.CDZ902  /* TOTAL BACKORDERED QTY */ 
       FROM MBCDREP LINES,
            MBCKREP HOLDS
      WHERE LINES.CDCVNB = HOLDS.CKCVNB AND /* SELECT ONLY LINES FROM ORDERS ON HOLD */ 
            LINES.CDDCCD = 1 AND /* ORDER TYPE: ORDER */  
            LINES.CDZ902 = 0 AND /* NO BACKORDERS */
            HOLDS.CKACP8 != '1') x /* HOLD NOT RELEASED */
GROUP BY x.CDA0CD
WITH ROLLUP 

给出我的结果:

 Item accounting                              "On Hold"  
 class                                                       
   LAY                                        8,357.290  
   LOC                                          909.570  
   MAR                                        2,666.340  
   MCT                                        4,933.970  
   SAF                                          378.000  
   STM                                          876.550  
   STN                                        4,739.800  
   TAG                                        2,709.280  
   TAP                                        6,670.930  
   VIS                                        1,885.100- 
   -                                         30,356.630  

对于延期交货订单:

SELECT y.CDA0CD, SUM(y.CDDUVA) AS "Back Orders"
  FROM (
     SELECT CDCVNB, /* QUOTE/ORDER NO */
            CDDCCD, /* ORDER TYPE */
            CDAITX, /* ITEM NUMBER */ 
            CDGLCD, /* ITEM CLASS */
            CDA0CD, /* IAC */
            CDDUVA, /* LC - NET SALES AMOUNT */     
            CDZ902  /* TOTAL BACKORDERED QTY */ 
       FROM MBCDREP
      WHERE CDDCCD = 1 AND /* ORDER TYPE: ORDER */  
            CDZ902 > 0) y /* BACKORDERS QTY GREATER THAN ZERO */
GROUP BY y.CDA0CD
WITH ROLLUP

结果:

 Item accounting                          "Back Orders"  
 class                                                       
  LOC                                           24.750  
  MAR                                          917.580  
  MCT                                       67,366.110  
  OTH                                             .000  
  STM                                           10.580  
  TAG                                        3,225.440  
  TAP                                          106.310  
  VIS                                       16,675.380  
  -                                         88,326.150  

我想把这些结合起来,再加上基于上述目标的其他总结。我可能需要一个完整的外部连接,这在 DB2 中不受支持,所以我尝试了一个复杂的左外部连接和一个右异常,但无济于事(有点遵循这个建议:https://www.mcpressonline.com/analytics-cognitive/db2/techtip-full-outer-joins-on-db2-for-i5os):

SELECT x.CDA0CD, x.CDDUVA AS On_Hold     
FROM (
     SELECT LINES.CDCVNB, /* QUOTE/ORDER NO */
            LINES.CDDCCD, /* ORDER TYPE */
            LINES.CDAITX, /* ITEM NUMBER */ 
            LINES.CDGLCD, /* ITEM CLASS */
            LINES.CDA0CD, /* IAC */
            LINES.CDDUVA, /* LC - NET SALES AMOUNT */
            HOLDS.CKCZCD, /* HOLD CODE */
            HOLDS.CKACP8, /* RELEASE TYPE */            
            LINES.CDZ902  /* TOTAL BACKORDERED QTY */ 
       FROM MBCDREP LINES,
            MBCKREP HOLDS
      WHERE LINES.CDCVNB = HOLDS.CKCVNB AND /* SELECT ONLY LINES FROM ORDERS 
ON HOLD */ 
            LINES.CDDCCD = 1 AND /* ORDER TYPE: ORDER */  
            LINES.CDZ902 = 0 AND /* NO BACKORDERS */
            HOLDS.CKACP8 != '1') x /* HOLD NOT RELEASED */
LEFT OUTER JOIN  
 (SELECT *
       FROM MBCDREP
      WHERE CDDCCD = 1 AND /* ORDER TYPE: ORDER */  
            CDZ902 > 0) y /* BACKORDERS QTY GREATER THAN ZERO */
ON x.CDA0CD = y.CDA0CD
UNION 
(SELECT yy.CDA0CD, 
    yy.CDDUVA AS Back_Orders 
FROM (
     SELECT CDCVNB, /* QUOTE/ORDER NO */
            CDDCCD, /* ORDER TYPE */
            CDAITX, /* ITEM NUMBER */ 
            CDGLCD, /* ITEM CLASS */
            CDA0CD, /* IAC */
            CDDUVA, /* LC - NET SALES AMOUNT */     
            CDZ902  /* TOTAL BACKORDERED QTY */ 
       FROM MBCDREP
      WHERE CDDCCD = 1 AND /* ORDER TYPE: ORDER */  
            CDZ902 > 0) yy
EXCEPTION JOIN 
(SELECT xx.CDA0CD, xx.CDDUVA AS On_Hold     
FROM (
     SELECT LINES.CDCVNB, /* QUOTE/ORDER NO */
            LINES.CDDCCD, /* ORDER TYPE */
            LINES.CDAITX, /* ITEM NUMBER */ 
            LINES.CDGLCD, /* ITEM CLASS */
            LINES.CDA0CD, /* IAC */
            LINES.CDDUVA, /* LC - NET SALES AMOUNT */
            HOLDS.CKCZCD, /* HOLD CODE */
            HOLDS.CKACP8, /* RELEASE TYPE */            
            LINES.CDZ902  /* TOTAL BACKORDERED QTY */ 
       FROM MBCDREP LINES,
            MBCKREP HOLDS
      WHERE LINES.CDCVNB = HOLDS.CKCVNB AND /* SELECT ONLY LINES FROM ORDERS 
ON HOLD */ 
            LINES.CDDCCD = 1 AND /* ORDER TYPE: ORDER */  
            LINES.CDZ902 = 0 AND /* NO BACKORDERS */
            HOLDS.CKACP8 != '1') xx) xxx 
    on yy.CDA0CD = xxx.CDA0CD   
            )

这只会给我暂停...

Item accounting              ON_HOLD   
class                                  
  TAP                     59.160   
  LAY                  1,668.000   
  LOC                     27.230   
  STM                     83.490   
  STM                     25.120   
  STM                     75.370   
  LAY                      1.500   
  LAY                     18.270   
  STN                     61.580   
  LAY                     23.040   
  MAR                      2.400   
  LAY                    218.680   
  TAG                    523.980   
  TAG                    524.040   
  LAY                  1,819.800   
  MCT                    470.400   
  TAG                     65.930   
  TAG                     33.630   
....

请帮忙!我知道必须有一个更简单的方法。我也有日期格式问题,但我会 post 将其作为一个单独的问题,因为它在技术上是一个不同的问题,但我最终会将它们结合在一起。

谢谢。

这是一种在 "Back Order" 上为 "On Hold" 创建 T 列的技术。结果中只有三列。易于添加更多类型 aka T。真正易于理解的输出格式。你必须尝试一下。我可能有语法错误,因为我刚刚输入。我可以将这种技术应用到 10000 个字符的语句中,因此它非常灵活。不是一个快速查询,但是一旦 运行 您需要的信息就在三列中。也许你找到了你要找的东西。

SELECT 'On Hold' as t, x.CDA0CD, SUM(x.CDDUVA) AS sumx    
  FROM (
     SELECT LINES.CDCVNB, /* QUOTE/ORDER NO */
            LINES.CDDCCD, /* ORDER TYPE */
            LINES.CDAITX, /* ITEM NUMBER */ 
            LINES.CDGLCD, /* ITEM CLASS */
            LINES.CDA0CD, /* IAC */
            LINES.CDDUVA, /* LC - NET SALES AMOUNT */
            HOLDS.CKCZCD, /* HOLD CODE */
            HOLDS.CKACP8, /* RELEASE TYPE */            
            LINES.CDZ902  /* TOTAL BACKORDERED QTY */ 
       FROM MBCDREP LINES,
            MBCKREP HOLDS
      WHERE LINES.CDCVNB = HOLDS.CKCVNB AND /* SELECT ONLY LINES FROM ORDERS ON HOLD */ 
            LINES.CDDCCD = 1 AND /* ORDER TYPE: ORDER */  
            LINES.CDZ902 = 0 AND /* NO BACKORDERS */
            HOLDS.CKACP8 != '1') x /* HOLD NOT RELEASED */
GROUP BY 'On Hold', x.CDA0CD
WITH ROLLUP 
union all
SELECT 'Back Orders' as t, y.CDA0CD, SUM(y.CDDUVA) AS sumx
  FROM (
     SELECT CDCVNB, /* QUOTE/ORDER NO */
            CDDCCD, /* ORDER TYPE */
            CDAITX, /* ITEM NUMBER */ 
            CDGLCD, /* ITEM CLASS */
            CDA0CD, /* IAC */
            CDDUVA, /* LC - NET SALES AMOUNT */     
            CDZ902  /* TOTAL BACKORDERED QTY */ 
       FROM MBCDREP
      WHERE CDDCCD = 1 AND /* ORDER TYPE: ORDER */  
            CDZ902 > 0) y /* BACKORDERS QTY GREATER THAN ZERO */
GROUP BY y.CDA0CD
WITH ROLLUP

Reader 注意:

请注意这只是一个建议:我不是 DB2 用户并且没有可用于测试的实例。 我将此作为答案而不是评论发布只是因为 OP 要求我详细说明并且评论没有足够的 space.


您似乎有一堆查询都是以下形式:

select CDA0CD, foo, bar, baz from ...

但是你错过了所有 CDA0CD 中的 table 来反对(想想:你错过了星型模式中的事实 table)。

您可以 "simulate" 在子查询中 table,例如。像这样的东西:

with CDA0CD as (
          select CDA0CD from whatever1
    union select CDA0CD from whatever2
    union select CDA0CD from whatever3
    union ...
) on_hold as (
    select CDA0CD, foo, bar, baz from whatever1
), back_orders as (
    select CDA0CD, foo, bar, baz from whatever2
), late as (
    ...
)
select CDA0CD.CDA0CD,
       on_hold.foo, on_hold.bar, on_hold.baz,
       back_orders.foo, back_orders.bar, back_orders.baz,
       ...
  from CDA0CD
       left join on_hold on on_hold.CDA0CD = CDA0CD.CDA0CD
       left join ...

甚至可能

with on_hold as (
    select CDA0CD, foo, bar, baz from whatever
), back_orders as (
    select CDA0CD, foo, bar, baz from whatever
), late as (
    ...
), CDA0CD as (
          select CDA0CD from on_hold
    union select CDA0CD from back_orders
    union select CDA0CD from late
)
select CDA0CD.CDA0CD,
       on_hold.foo, on_hold.bar, on_hold.baz,
       back_orders.foo, back_orders.bar, back_orders.baz,
       ...
  from CDA0CD
       left join on_hold on on_hold.CDA0CD = CDA0CD.CDA0CD
       left join ...

试试这个

select CDA0CD,总和(保留值),总和(延期交货值) 从 ( /* 保留查询 <em>/ select CDA0CD , SUM(CDDUVA) 作为持有值,0 作为延期交货值 …… /</em> 保留查询 <em>/ 联合所有 /</em>延期查询<em>/ select CDA0CD , 0 作为 holdvalue , SUM(CDDUVA) 作为延期交货值 …… /</em>缺货查询*/ ) 按 CDA0CD 分组