You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:20:27