为何两条相似SQL查询结果不同?主表与子表关联逻辑解析
差异原因与关联逻辑解析
1. 为什么两个SQL结果不同?
E1的逻辑缺陷
E1中子查询的条件e1.log_number=2是对主表e1当前行的属性判断,而非对子表e2的筛选。具体执行时:
- 主查询先筛选出
user_id=131的两行(log_number都是2)。 - 对主表的每一行,子查询会找
fusion.employee中user_id等于当前e1.user_id(131)的所有行,再取最大last_update_date——这里e1.log_number=2只是确认主表当前行的log_number是2,完全不限制子表e2的log_number范围。 - 如果
fusion.employee中user_id=131的行包含其他log_number的记录(比如log_number=3且更新时间更晚),子查询返回的max值就会超出主表现有行的更新时间,导致主表没有行满足last_update_date IN(...),最终返回空结果。 - 另外,SQL中
e1.log_number=2.的小数点可能引发类型不匹配(比如log_number是整数类型,2.被解析为浮点数),导致子查询条件不成立,返回空集合,主表自然无匹配。
E2的正确逻辑
E2中子查询的条件e2.log_number=2是对子表e2的行进行筛选,逻辑清晰:
- 对主表的每一行,子查询仅在
fusion.employee中找user_id=e1.user_id且log_number=2的行,再取这些行的最大last_update_date(即2024-12-17 16:49:18.087)。 - 主表中
user_id=131且last_update_date等于该最大值的行,正好是目标记录,因此被正确返回。
2. 主表e1与子表e2的关联逻辑
这是典型的关联子查询(Correlated Subquery),核心是子查询引用了主查询的字段(e2.user_id = e1.user_id),执行流程为:
- 主查询先执行外层过滤
e1.user_id=131,得到候选行集合。 - 对候选集合中的每一行e1,单独触发一次子查询:
- 根据子查询的WHERE条件筛选子表e2的行(E1和E2的筛选规则不同)。
- 计算筛选后行的
max(last_update_date),得到一个单一值(或空)。
- 主查询校验当前e1行的
last_update_date是否在子查询返回的结果中,符合条件则保留该行。
简单说:关联子查询是“主表每走一行,子表跟着查一次”,子查询的结果完全依赖当前主表行的属性值。
内容的提问来源于stack exchange,提问作者biswajeet SARKAR
相关产品推荐
相关产品推荐

