接收 DB2 中列 SUM 的不同输出
Receiving different output for column SUMs in DB2
我在 DB2 中有以下 table:
COLUMN_NAME
DATA_TYPE
TYPE_NAME
COLUMN_SIZE
COLUMN_TEXT
DMPROD
-2
CHAR () FOR BIT DATA
35
产品代码
DMPTYP
-2
CHAR () FOR BIT DATA
1
期间类型
DM类型
-2
CHAR () FOR BIT DATA
6
数据类型
DMVL01
3
十进制
17
价值周期 1
DMVL02
3
十进制
17
价值周期 2
DMVL03
3
十进制
17
价值周期 3
DMVL04
3
十进制
17
价值周期 4
DMVL05
3
十进制
17
价值周期 5
DMVL06
3
十进制
17
价值周期 6
DMVL07
3
十进制
17
价值周期 7
DMVL08
3
十进制
17
价值周期 8
DMVL09
3
十进制
17
价值周期 9
DMVL10
3
十进制
17
价值周期 10
DMVL11
3
十进制
17
价值周期 11
DMVL12
3
十进制
17
价值周期 12
二年
3
十进制
4
财政年度
下面的查询将return每个周期类型的价值周期总和,将它们分组到产品代码
SELECT
D.DMPROD,
Sum(D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06) AS Total
FROM
DWM D
WHERE
D.DMYEAR IN (2022)
AND D.DMPTYP = 'M'
AND D.DMTYPE IN ('RTNQTY','SLSQTY')
GROUP BY
D.DMPROD
ORDER BY
1;
初始输出:
DMPROD
总计
11105
1145.75000
11350
625.37400
13135
2270.50000
13282
-0.27500
13344
-1.03300
15105
784
然后,由于其他成员的反馈,我将其更改为使用子查询。这是首选格式:
SELECT
D.DMPROD,
(SLSQTY + RTNQTY) AS Total
FROM
(
SELECT
D.DMPROD,
Sum(CASE WHEN D.DMTYPE = 'RTNQTY' THEN Total END) AS RTNQTY,
Sum(CASE WHEN D.DMTYPE = 'SLSQTY' THEN Total END) AS SLSQTY
FROM
(
SELECT
D.*,
(D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06) AS Total
FROM
DWM AS D
) AS D
WHERE
D.DMYEAR IN (2022)
AND D.DMPTYP = 'M'
GROUP BY
D.DMPROD
) AS D
ORDER BY 1;
但注意总和不一样(初始输出是正确的):
DMPROD
总计
11105
1145.75000
11350
625.37400
13135
2270.50000
13282
13344
15105
我哪里算错了?
可能会出现某些 DMPROD
组不包含某些 DMTYPE
的行的情况。此类型的 SUM 为 NULL,如果在 +
运算符中使用此类值,则结果为 NULL。
您可以按原样检查以下示例:
SELECT
DMPROD
, RTNQTY
, SLSQTY
, RTNQTY + SLSQTY AS TOTAL_new
, TOTAL_orig
, COALESCE (RTNQTY, 0) + COALESCE (SLSQTY, 0) AS TOTAL_mustbe
FROM
(
SELECT
DMPROD
, SUM (CASE WHEN DMTYPE = 'RTNQTY' THEN Total END) AS RTNQTY
, SUM (CASE WHEN DMTYPE = 'SLSQTY' THEN Total END) AS SLSQTY
, SUM (Total) AS TOTAL_orig
FROM
(
VALUES
(1, 'RTNQTY', 1)
, (1, 'SLSQTY', 1)
, (2, 'RTNQTY', 1)
) MY_TAB (DMPROD, DMTYPE, Total)
GROUP BY DMPROD
);
结果是:
DMPROD
RTNQTY
SLSQTY
TOTAL_NEW
TOTAL_ORIG
TOTAL_MUSTBE
1
1
1
2
2
2
2
1
1
1
这些表达式:
Sum(CASE WHEN D.DMTYPE = 'RTNQTY' THEN Total END) AS RTNQTY,
Sum(CASE WHEN D.DMTYPE = 'SLSQTY' THEN Total END) AS SLSQTY
如果结果中没有 DMTYPE
的行, 可以 return NULL
。反过来,这会影响此计算:
(SLSQTY + RTNQTY) AS Total
最简单的解决方案是添加ELSE 0
:
Sum(CASE WHEN D.DMTYPE = 'RTNQTY' THEN Total ELSE 0 END) AS RTNQTY,
Sum(CASE WHEN D.DMTYPE = 'SLSQTY' THEN Total ELSE 0 END) AS SLSQTY
这样就避免了NULL
的值,所以总计算不会变成NULL
。
我在 DB2 中有以下 table:
COLUMN_NAME | DATA_TYPE | TYPE_NAME | COLUMN_SIZE | COLUMN_TEXT |
---|---|---|---|---|
DMPROD | -2 | CHAR () FOR BIT DATA | 35 | 产品代码 |
DMPTYP | -2 | CHAR () FOR BIT DATA | 1 | 期间类型 |
DM类型 | -2 | CHAR () FOR BIT DATA | 6 | 数据类型 |
DMVL01 | 3 | 十进制 | 17 | 价值周期 1 |
DMVL02 | 3 | 十进制 | 17 | 价值周期 2 |
DMVL03 | 3 | 十进制 | 17 | 价值周期 3 |
DMVL04 | 3 | 十进制 | 17 | 价值周期 4 |
DMVL05 | 3 | 十进制 | 17 | 价值周期 5 |
DMVL06 | 3 | 十进制 | 17 | 价值周期 6 |
DMVL07 | 3 | 十进制 | 17 | 价值周期 7 |
DMVL08 | 3 | 十进制 | 17 | 价值周期 8 |
DMVL09 | 3 | 十进制 | 17 | 价值周期 9 |
DMVL10 | 3 | 十进制 | 17 | 价值周期 10 |
DMVL11 | 3 | 十进制 | 17 | 价值周期 11 |
DMVL12 | 3 | 十进制 | 17 | 价值周期 12 |
二年 | 3 | 十进制 | 4 | 财政年度 |
下面的查询将return每个周期类型的价值周期总和,将它们分组到产品代码
SELECT
D.DMPROD,
Sum(D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06) AS Total
FROM
DWM D
WHERE
D.DMYEAR IN (2022)
AND D.DMPTYP = 'M'
AND D.DMTYPE IN ('RTNQTY','SLSQTY')
GROUP BY
D.DMPROD
ORDER BY
1;
初始输出:
DMPROD | 总计 |
---|---|
11105 | 1145.75000 |
11350 | 625.37400 |
13135 | 2270.50000 |
13282 | -0.27500 |
13344 | -1.03300 |
15105 | 784 |
然后,由于其他成员的反馈,我将其更改为使用子查询。这是首选格式:
SELECT
D.DMPROD,
(SLSQTY + RTNQTY) AS Total
FROM
(
SELECT
D.DMPROD,
Sum(CASE WHEN D.DMTYPE = 'RTNQTY' THEN Total END) AS RTNQTY,
Sum(CASE WHEN D.DMTYPE = 'SLSQTY' THEN Total END) AS SLSQTY
FROM
(
SELECT
D.*,
(D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06) AS Total
FROM
DWM AS D
) AS D
WHERE
D.DMYEAR IN (2022)
AND D.DMPTYP = 'M'
GROUP BY
D.DMPROD
) AS D
ORDER BY 1;
但注意总和不一样(初始输出是正确的):
DMPROD | 总计 |
---|---|
11105 | 1145.75000 |
11350 | 625.37400 |
13135 | 2270.50000 |
13282 | |
13344 | |
15105 |
我哪里算错了?
可能会出现某些 DMPROD
组不包含某些 DMTYPE
的行的情况。此类型的 SUM 为 NULL,如果在 +
运算符中使用此类值,则结果为 NULL。
您可以按原样检查以下示例:
SELECT
DMPROD
, RTNQTY
, SLSQTY
, RTNQTY + SLSQTY AS TOTAL_new
, TOTAL_orig
, COALESCE (RTNQTY, 0) + COALESCE (SLSQTY, 0) AS TOTAL_mustbe
FROM
(
SELECT
DMPROD
, SUM (CASE WHEN DMTYPE = 'RTNQTY' THEN Total END) AS RTNQTY
, SUM (CASE WHEN DMTYPE = 'SLSQTY' THEN Total END) AS SLSQTY
, SUM (Total) AS TOTAL_orig
FROM
(
VALUES
(1, 'RTNQTY', 1)
, (1, 'SLSQTY', 1)
, (2, 'RTNQTY', 1)
) MY_TAB (DMPROD, DMTYPE, Total)
GROUP BY DMPROD
);
结果是:
DMPROD | RTNQTY | SLSQTY | TOTAL_NEW | TOTAL_ORIG | TOTAL_MUSTBE |
---|---|---|---|---|---|
1 | 1 | 1 | 2 | 2 | 2 |
2 | 1 | 1 | 1 |
这些表达式:
Sum(CASE WHEN D.DMTYPE = 'RTNQTY' THEN Total END) AS RTNQTY,
Sum(CASE WHEN D.DMTYPE = 'SLSQTY' THEN Total END) AS SLSQTY
如果结果中没有 DMTYPE
的行, 可以 return NULL
。反过来,这会影响此计算:
(SLSQTY + RTNQTY) AS Total
最简单的解决方案是添加ELSE 0
:
Sum(CASE WHEN D.DMTYPE = 'RTNQTY' THEN Total ELSE 0 END) AS RTNQTY,
Sum(CASE WHEN D.DMTYPE = 'SLSQTY' THEN Total ELSE 0 END) AS SLSQTY
这样就避免了NULL
的值,所以总计算不会变成NULL
。