连接两个分组子查询 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 分组
下午好,
我正在尝试创建一个每日销售报告摘要,加入几个不同的文件并根据不同的因素进行总结。
报告将以如下形式结束:
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 分组