MySQL使用NOT条件时SUM返回NULL的问题求助
SQL SUM计算异常排查:NOT条件返回NULL的原因
问题场景
以下SQL语句能返回正确的SUM结果:
SELECT SUM(factura_ron) AS total_ron, SUM(factura_eur) AS total_eur, SUM(factura_usd) AS total_usd FROM facturi WHERE (status_id = 2 OR status_id = 4 OR status_id = 6) AND (factura_type_id IS NULL OR factura_type_id = 1 OR factura_type_id = 2 OR factura_type_id = 4)
但使用NOT条件的语句返回的SUM全为NULL,尝试过以下几种写法:
写法1:
SELECT SUM(factura_ron) AS total_ron, SUM(factura_eur) AS total_eur, SUM(factura_usd) AS total_usd FROM facturi WHERE (status_id = 2 OR status_id = 4 OR status_id = 6) AND NOT (factura_type_id = 3 OR factura_type_id = 5)
写法2:
SELECT SUM(factura_ron) AS total_ron, SUM(factura_eur) AS total_eur, SUM(factura_usd) AS total_usd FROM facturi WHERE status_id IN (2, 4, 6) AND factura_type_id NOT IN (3, 5)
写法3:
SELECT SUM(factura_ron) AS total_ron, SUM(factura_eur) AS total_eur, SUM(factura_usd) AS total_usd FROM facturi WHERE status_id IN (2, 4, 6) AND factura_type_id <> 3 AND factura_type_id <> 5
字段说明
STATUS(状态)
- Status NULL:已发送
- Status 2:已支付
- Status 4:预付
- Status 6:分期支付
TYPE(单据类型)
- Factura type NULL:标准
- Factura Type 1:仓储
- Factura Type 2:维护
- Factura Type 3:押金
- Factura Type 4:冲销
- Factura Type 5:押金冲销
测试数据(仅展示factura_usd列)
ID factura_usd factura_type status_id 1 20 5 null 2 10 5 2 3 -10 3 2 4 100 5 2 5 -100 3 null 6 2000 5 2 7 2300 null null 8 550 null 2
预期factura_usd的求和结果为550 USD(第一个语句可得到),但使用排除Type3和Type5的语句时返回NULL,两种语句逻辑看似一致,问题出在哪?
问题根源:NULL值的逻辑判断特性
SQL中,NULL和任何值进行比较的结果都是UNKNOWN,而非TRUE或FALSE。WHERE子句只会保留判断结果为TRUE的行,UNKNOWN的行会被过滤。
第一个语句明确包含了factura_type_id IS NULL的条件,所以会保留factura_type_id为NULL且status_id符合要求的行(即测试数据中的ID8),因此能计算出正确的SUM值。
而使用NOT条件的写法中:
NOT (factura_type_id = 3 OR factura_type_id = 5):当factura_type_id为NULL时,factura_type_id =3和factura_type_id=5的结果都是UNKNOWN,OR运算后还是UNKNOWN,NOT UNKNOWN仍然是UNKNOWN,因此该行被过滤。factura_type_id NOT IN (3,5):等价于NOT (factura_type_id=3 OR factura_type_id=5),同样会过滤掉factura_type_id为NULL的行。factura_type_id <>3 AND factura_type_id <>5:当factura_type_id为NULL时,两个比较结果都是UNKNOWN,AND运算后还是UNKNOWN,该行被过滤。
最终,使用NOT条件的语句没有符合要求的行,SUM函数对空数据集返回NULL。
解决方法
需要明确包含factura_type_id IS NULL的判断,修改WHERE条件为:
WHERE status_id IN (2,4,6) AND (factura_type_id IS NULL OR factura_type_id NOT IN (3,5))
这样就能保留factura_type_id为NULL且状态符合要求的行,得到正确的SUM结果。
内容的提问来源于stack exchange,提问作者user1286956
相关产品推荐
相关产品推荐

