小本本记一下,工作中看同事的代码遇到这个问题。
同事开发的存储过程,把条件放在from后面 和where后面。想当然的情况下好像没啥区别。
但是sql 的执行顺序是第一步执行 from 后面的语句,第二步执行where 后面的语句。
在这里用oralce 举个例子,不同DBMS的sql基本大同小异。
1、数据准备:
在另一篇笔记中:oracle pivot unpivot 行列互换
insert into test001
select t.id_test, t.col_int, t.col_int, t.col_int, t.col_int, t.col_int
from test002 t
where t.id_test like '%A%';
2、查询结果
- 查询1,条件放在from 后面:
select t1.id_test as t1_id, t2.id_test as t2_id
from test002 t2
left join test001 t1
on t1.id_test = t2.id_test
and t1.id_test is null;
-
结果1:
-
查询2,条件放在where 后面:
select t1.id_test as t1_id, t2.id_test as t2_id
from test002 t2
left join test001 t1
on t1.id_test = t2.id_test
where t1.id_test is null;
- 结果2:
- 查询3,全连接:
select t1.id_test as t1_id, t2.id_test as t2_id
from test002 t2
full join test001 t1
on t1.id_test = t2.id_test;
- 结果3:
- 查询4:
select t1.id_test as t1_id, t2.id_test as t2_id
from test002 t2
left join (select * from test001 where id_test is null) t1
on t1.id_test = t2.id_test;
- 结果4:
3、结果简单分析
- 结果1可以看到,在执行from的时候,关联两张表首先用条件 t1.id_test is null 把 t1的数据先过滤,然后再和 t2表做关联,结果只剩下t2表的所有记录(t2表的5条记录)。
- 结果2可以看到,在执行from的时候,首先把t1表的所有记录和t2表的所有记录做匹配,然后在where 子句中使用条件 t1.id_test is null 把两表关联的结果集过滤,剩下符合条件的记录(4条记录,把匹配到的t1和t2共同的记录 ID_TEST='APPLE’剔除)。
- 结果3可以看到,侧面印证结果2是怎么来的。
- 结果4可以看到,侧面印证结果1是怎么来的。