如何用单条SQL语句判断两个查询的item_id结果是否相等?
单条SQL判断两个查询结果是否相等
先看数据表结构及数据:
| package_id | item_id |
|---|---|
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 3 | 1 |
| 3 | 2 |
需求是用单条SQL判断以下两个查询的结果是否完全相等:
查询1:
SELECT item_id FROM table WHERE package_id = 1
查询2:
SELECT item_id FROM table WHERE package_id = 3
为什么单纯用EXCEPT或NOT IN无法满足需求
你提到的示例语句只检查了单方向的子集关系,但要判断两个集合完全相等,必须同时满足A是B的子集且B是A的子集;如果需要考虑元素的重复次数,还要保证两个集合的元素总数一致,单方向的校验无法覆盖这些场景。
解决方案
方法1:双向EXCEPT+数量校验(兼容多数数据库)
这种方法同时验证双向子集关系,并且可选校验元素重复次数是否一致:
SELECT CASE WHEN ( -- 检查查询1的所有结果都在查询2中 NOT EXISTS ( SELECT item_id FROM table WHERE package_id = 1 EXCEPT SELECT item_id FROM table WHERE package_id = 3 ) -- 检查查询2的所有结果都在查询1中 AND NOT EXISTS ( SELECT item_id FROM table WHERE package_id = 3 EXCEPT SELECT item_id FROM table WHERE package_id = 1 ) -- 可选:如果需要验证元素重复次数一致,加上数量判断 AND (SELECT COUNT(*) FROM table WHERE package_id = 1) = (SELECT COUNT(*) FROM table WHERE package_id = 3) ) THEN '相等' ELSE '不相等' END AS result
如果只需要判断元素集合(不关心重复次数),可以去掉最后的数量校验部分。
方法2:聚合拼接比较(适合支持字符串聚合的数据库)
通过将两个查询的结果按固定顺序拼接成字符串,直接比较字符串是否相等:
-- PostgreSQL/SQL Server 用法 SELECT CASE WHEN ( SELECT STRING_AGG(item_id, ',' ORDER BY item_id) FROM table WHERE package_id = 1 = SELECT STRING_AGG(item_id, ',' ORDER BY item_id) FROM table WHERE package_id = 3 ) THEN '相等' ELSE '不相等' END AS result -- MySQL 用法 SELECT CASE WHEN ( SELECT GROUP_CONCAT(item_id ORDER BY item_id SEPARATOR ',') FROM table WHERE package_id = 1 = SELECT GROUP_CONCAT(item_id ORDER BY item_id SEPARATOR ',') FROM table WHERE package_id = 3 ) THEN '相等' ELSE '不相等' END AS result
这种方法简单直观,但要注意元素拼接时必须排序,否则结果顺序不同会导致误判;同时如果item_id包含分隔符(比如逗号),需要换用其他无冲突的分隔符。
内容的提问来源于stack exchange,提问作者Tomasz Mateusz
相关产品推荐
相关产品推荐

