MySQL二叉树节点类型查询中NOT IN用法异常排查
错误原因
你写的SQL无法得到正确结果的核心问题是NOT IN子查询存在NULL值陷阱:
你用到的子查询SELECT DISTINCT P FROM BST返回的结果集中包含根节点的父节点值NULL,而SQL的三值逻辑规则下,只要NOT IN对应的集合里存在NULL,整个判断结果就会返回UNKNOWN,而不是你预期的TRUE,导致叶子节点的判断条件永远无法命中,最终结果错误。
修复方案
你可以任选以下任意一种方案修改:
方案1:过滤子查询中的NULL值
只需要在子查询里排除NULL的P值即可:
select case when P is NULL then CONCAT_WS(" ", N, 'Root') when N not in (SELECT DISTINCT P FROM BST WHERE P IS NOT NULL) then CONCAT_WS(" ", N, 'Leaf') else CONCAT_WS(" ", N, 'Inner') end from BST ORDER BY N ASC;
方案2:用NOT EXISTS替换NOT IN(更稳妥)
EXISTS天然避开NULL值问题,兼容性更高:
select case when P is NULL then CONCAT_WS(" ", N, 'Root') when NOT EXISTS (SELECT 1 FROM BST b WHERE b.P = t.N) then CONCAT_WS(" ", N, 'Leaf') else CONCAT_WS(" ", N, 'Inner') end from BST t ORDER BY N ASC;
注意事项
- 涉及到子查询的IN/NOT IN判断时,一定要确认子查询结果不会包含NULL值,否则会出现不符合预期的结果
- 生产环境更推荐用EXISTS类写法,避免踩NULL值的逻辑陷阱
内容的提问来源于stack exchange,提问作者user_12
相关产品推荐
相关产品推荐

