SQL中exists运算符作用疑问:含exists的关联子查询过滤逻辑求解
问题原因解答
核心逻辑是你写的SQL属于相关子查询,子查询的结果依赖主查询当前遍历的t1行的字段值,因此会对主查询的所有行做隐式过滤,效果和你手动加t1.user_ID= 123456完全一致,具体执行逻辑拆解如下:
- 主查询会遍历
MY_TABLE中的每一行记为t1,对每一行单独执行一次WHERE后的子查询 - 子查询中
exists代码块用到了外层的t1.user_ID作为过滤条件:t1.user_ID=thirdTable.id,同时exists代码块内还有关联关系链:
这组关联条件已经限定了:只有当thirdTable.second_table_parent_id = mySecondTable.parent_ID mySecondTable.test_id = t2.id t2.user_ID = 123456t1.user_ID对应的thirdTable行,能关联到归属user_ID=123456的t2行时,exists判断才会返回真 - 如果
t1.user_ID不等于123456,exists判断返回假,此时子查询的max(t2.version_nr)结果为NULL,而SQL中任何值 = NULL的判断结果都为假,因此这行t1会直接被过滤 - 只有
t1.user_ID符合关联要求(实际就是等于123456)、且version_nr等于子查询返回的最大值3的行才会被保留,因此最终只返回1条结果
你直接执行select * from MY_TABLE t1 where t1.version_nr=3返回多条结果,是因为没有上述的关联过滤逻辑,所有version_nr=3的行都会被返回,和原查询的过滤逻辑有本质区别。
内容的提问来源于stack exchange,提问作者מאיר חן
相关产品推荐
相关产品推荐

