SQL查询:判断id是否存在于p_id列 列转逗号分隔列表方法
问题背景
- 本人是SQL初学者,目前在练习LeetCode第608题,不需要直接提供题解,仅咨询相关SQL语法实现问题
- 用到的
tree表共2个字段:id:int类型p_id:int类型
- 核心需求:逐行判断每个
id值是否存在于p_id列的全量值中
遇到的问题
- 最初尝试写的测试SQL如下:
SELECT id NOT IN (p_id) FROM tree
- 参考给定测试输入,期望得到的布尔值结果为
(1, 1, 0, 0, 0) - 目前已知上述语句无法正常生效,原因是写法中的
p_id是逐行读取的单个值,并非NOT IN语法要求的值集合,因此想确认两个问题:- 是否有方法可以将整列数据转换为逗号分隔的值列表,供
NOT IN语法使用? - 是否有其他实现思路可以得到预期的查询结果?
- 是否有方法可以将整列数据转换为逗号分隔的值列表,供
实现方案
不需要特意把整列转成逗号分隔的列表,SQL原生支持直接将子查询返回的结果集作为IN/NOT IN的匹配范围,你之前写法的问题是括号内直接写了列名,数据库只会读取当前行的p_id单值做判断,不会取全表的p_id集合。
方案1:修正NOT IN写法
直接在括号内写子查询,查询全表非空的p_id作为匹配集合即可:
SELECT id NOT IN (SELECT p_id FROM tree WHERE p_id IS NOT NULL) AS check_result FROM tree;
这里必须加WHERE p_id IS NOT NULL的过滤条件:NOT IN对NULL值的处理存在特殊逻辑——如果子查询返回的结果里包含NULL,所有行的NOT IN判断都会返回NULL,无法得到你预期的0/1布尔结果。
方案2:用EXISTS逻辑实现(更推荐)
数据量较大时EXISTS的性能通常比NOT IN更稳定,逻辑是判断当前行的id是否能在p_id列找到匹配记录:
SELECT CASE WHEN EXISTS (SELECT 1 FROM tree t2 WHERE t2.p_id = t1.id) THEN 0 ELSE 1 END AS check_result FROM tree t1;
语句中EXISTS找到匹配项时返回真,对应结果0(表示当前id存在于p_id列中),找不到匹配项时返回1,和你预期的输出完全一致。
注意:不要尝试手动将列值拼接为逗号分隔字符串来实现该需求。字符串拼接后是文本格式,做值匹配时不仅性能差,还容易出现类型转换错误、值匹配偏差的问题,属于SQL编写的反模式。
内容的提问来源于stack exchange,提问作者jcjcjcjc
相关产品推荐
相关产品推荐

