当branch_s无subbranch列时,带IN子句的SQL查询为何返回branch_m全量数据?
为什么这个SQL查询返回了所有BRANCH值?
这是一个典型的列名解析歧义踩坑问题,咱们一步步拆解清楚:
核心问题:列名的“向上查找”逻辑
你的SQL语句里,子查询SELECT subbranch FROM branch_s中,subbranch列在branch_s表根本不存在。但数据库的解析器不会直接报错,它会遵循作用域规则——如果当前子查询的表找不到对应列,就会向上查找外层查询的表是否有这个列。这里正好外层的branch_m表有SUBBRANCH列,所以解析器直接把subbranch解析成了branch_m.SUBBRANCH。
逻辑被悄悄改写了
原本你期望的逻辑是:“找出branch_m中SUBBRANCH存在于branch_s的subbranch列(不存在的列)的行”,但实际执行的逻辑变成了一个相关子查询:
- 遍历
branch_m的每一行 - 对于当前行,判断该行的
SUBBRANCH是否存在于「从branch_s中取出当前行的SUBBRANCH值组成的集合」 - 因为
branch_s有2行数据,子查询会返回两个完全相同的当前行SUBBRANCH值,比如第一行SUBBRANCH=CS,子查询返回(CS, CS),那么CS IN (CS, CS)必然为真
所以每一行的IN条件都满足,自然返回了branch_m的所有BRANCH值。
怎么避免这种坑?
最稳妥的方式是给表加别名,引用列时必须带上别名,比如把SQL改成:
SELECT bm.BRANCH FROM branch_m bm WHERE bm.SUBBRANCH IN (SELECT bs.SUBBRANCH FROM branch_s bs)
这样数据库会直接发现bs.SUBBRANCH不存在,抛出明确的错误,而不是偷偷改写逻辑让你摸不着头脑。
内容的提问来源于stack exchange,提问作者nagraj036
相关产品推荐
相关产品推荐

