为何Oracle中该SQL查询无报错?结果是否与正确查询一致?
关于Oracle中SQL查询不报错及结果一致性的解析
一、第一个查询不报错的原因
Oracle对未指定表别名的列遵循内层表优先、外层表次之的解析规则:
- 子查询中的
field_99,Oracle会先在子查询的table_2中查找该列,发现不存在后,会自动向上匹配外层查询的table_1(因为table_1包含field_99),最终将field_99解析为table_1.field_99,因此不会触发"列不存在"的报错。 - 此时该子查询已成为关联子查询,外层
table_1的每一行记录都会代入子查询中完成条件判断。
二、两个查询的结果一致
虽然写法不同,但两个查询的逻辑等价,返回结果完全一致:
第一个查询的逻辑拆解
对于table_1的每一行记录,同时满足两个条件:
- 自身的
field_99符合LIKE匹配规则; - 存在
table_2中field_2='0000'且field_1与当前table_1.field_1相等的记录。
等价改写为:
SELECT * FROM table_1 t1 WHERE EXISTS ( SELECT 1 FROM table_2 t2 WHERE t2.field_2 = '0000' AND t2.field_1 = t1.field_1 AND (t1.field_99 LIKE '%AAA%' OR t1.field_99 LIKE '%BBB%' OR t1.field_99 LIKE '%CCC%') );
第二个查询的逻辑拆解
先从table_2中提取所有field_2='0000'的field_1值形成集合,再筛选table_1中满足以下两个条件的记录:
field_1属于上述集合;field_99符合LIKE匹配规则。
等价改写为:
SELECT t1.* FROM table_1 t1 JOIN (SELECT DISTINCT field_1 FROM table_2 WHERE field_2='0000') t2 ON t1.field_1 = t2.field_1 WHERE (t1.field_99 LIKE '%AAA%' OR t1.field_99 LIKE '%BBB%' OR t1.field_99 LIKE '%CCC%');
两种写法最终都会筛选出table_1中field_99符合规则且field_1在table_2的field_2='0000'对应集合里的记录,结果完全一致。
内容的提问来源于stack exchange,提问作者Alexey
相关产品推荐
相关产品推荐

