SQL多<>条件查询结果异常,逻辑不符预期求助
问题分析:多<>条件AND连接的逻辑错误
现有表t1,包含id(UUID)、id_e(UUID)、category(VARCHAR)三个字段,总数据量700000行。
执行精准匹配某一行的查询时,返回0行(确认该行不存在):
SELECT COUNT(*) FROM t1 WHERE id = '7ea67ae0-aef8-4944-bfb4-b9e04b42143a'::UUID AND id_e = 'fa9763f5-c9e0-4de3-be57-ab3149fb1b9f'::UUID AND category = 'A+'
结果:
| count |
|---|
| 0 |
但执行以下排除条件的查询时,返回385221行,远小于总数据量:
SELECT COUNT(*) FROM t1 WHERE id <> '7ea67ae0-aef8-4944-bfb4-b9e04b42143a'::UUID AND id_e <> 'fa9763f5-c9e0-4de3-be57-ab3149fb1b9f'::UUID AND category <> 'A+'
结果:
| count |
|---|
| 385221 |
问题根源
你写的第二个查询逻辑是只统计三个字段同时不等于目标值的行,但这和「排除掉那一行(三个字段同时匹配的行)」的预期完全不符。
举个具体例子:
- 若某行
id等于目标值,但id_e和category不等于,这行不会被第一个查询命中,但也不会被第二个查询统计(因为第二个查询要求id <> 目标值,不满足AND连接的所有条件) - 同理,
id_e等于目标值但其他两个不等的行,或者category等于目标值但其他两个不等的行,都会被第二个查询排除在外
这些被漏掉的行,加上第二个查询的385221行,再加上第一个查询的0行,总数才等于表的总数据量700000。
正确的写法
如果你的意图是统计「除了三个条件同时匹配的行之外的所有行」(因该行不存在,结果应等于总数据量),应该用NOT包裹原匹配条件:
SELECT COUNT(*) FROM t1 WHERE NOT ( id = '7ea67ae0-aef8-4944-bfb4-b9e04b42143a'::UUID AND id_e = 'fa9763f5-c9e0-4de3-be57-ab3149fb1b9f'::UUID AND category = 'A+' )
这样就能得到700000行的结果,因为原匹配条件返回0行,取反后就是所有行。
内容的提问来源于stack exchange,提问作者VeryNiceArgumentException
相关产品推荐
相关产品推荐

