加入两个分组的子查询IBM i,DB2 SQL

时间:2018-02-12 20:43:04

标签: sql join db2 aggregate-functions full-outer-join

下午好,

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

报告最终结果如下:

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中是不受支持的,所以我尝试了一个复杂的Left Outer Join和Right Exceptions,但无济于事(有点像这个建议: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   
....

请帮忙!我知道必须有一个更简单的方法。我也有日期格式问题,但我会将其作为一个单独的问题发布,因为它在技术上是一个不同的问题,尽管我最终会将它们加在一起。< / p>

感谢。

3 个答案:

答案 0 :(得分:1)

这是一种在“后退订单”中为“暂停”创建T列的技术。结果中只有三列。容易添加更多类型又名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

答案 1 :(得分:1)

试试这个

select CDA0CD , sum(holdvalue) , sum(backordervalue) from ( /* hold query / select CDA0CD , SUM(CDDUVA) as holdvalue , 0 as backordervalue ...... / hold query / union all / backorder query / select CDA0CD , 0 as holdvalue , SUM(CDDUVA) as backordervalue ...... / backorder query */ ) group by CDA0CD

答案 2 :(得分:0)

读者要小心:

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

您似乎有很多查询都在表单中:

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

但是你错过了一个所有要加入的CDA0CD的表(想想:你错过了星型模式中的事实表)。

您可以在子查询中“模拟”该表,例如。有类似的东西:

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 ...