理解篩選條件在on和where中的區別,最好先理解sql的執行順序,盡管實際執行時不同的物理執行引擎可能會有特定的優化,但是邏輯執行順序必須遵循:
1)
from
:確定數據源是什么,from后可以是單表,可以是多表的join操作。
2)where
:對from的數據源進行篩選。
3)group by
:對where篩選后的結果分組。
4)having
:對group by分組后的結果進行過濾(注意此時過濾的數據粒度不是單條記錄,而是整個分組)。
5)select
:選擇結果字段(窗口函數的執行時機也在此時)。
6)order by
:對select的結果執行排序。
7)limit
:限制最終的結果數量。
所以從執行順序可以看出篩選條件放在where和on中,最本質的區別是過濾的時機不同,on中的過濾發生在join的過程中,影響的是匹配邏輯,并不影響參與關聯的數據集本身。而where中的過濾是對join之后的結果集進行過濾。
篩選條件放在on中:
drop view if exists employees;
create temporary view employees as
select 1 as emp_id, '張三' as name, 10 as dept_id
union all
select 2, '李四', 20
union all
select 3, '王五', null;drop view if exists departments;
create temporary view departments as
select 10 as dept_id, '技術部' as dept_name, 'active' as status
union all
select 20, '市場部', 'inactive'
union all
select 30, '財務部', 'active';select *
from employees e
left join departments d on e.dept_id=d.dept_id and d.status='active';
保留了左表的全部記錄,邏輯上和先從右表篩選,拿篩選后的結果和左表關聯的效果一樣。
放在where中:
drop view if exists employees;
create temporary view employees as
select 1 as emp_id, '張三' as name, 10 as dept_id
union all
select 2, '李四', 20
union all
select 3, '王五', null;drop view if exists departments;
create temporary view departments as
select 10 as dept_id, '技術部' as dept_name, 'active' as status
union all
select 20, '市場部', 'inactive'
union all
select 30, '財務部', 'active';select *
from employees e
left join departments d on e.dept_id=d.dept_id where d.status='active';
tips
執行邏輯上,on只影響匹配邏輯,而不影響參與關聯匹配的數據集本身,因此如果在左連接 left join 中用on對左表進行條件限制,左表依然會全部保留。
drop view if exists employees;
create temporary view employees as
select 1 as emp_id, '張三' as name, 10 as dept_id
union all
select 2, '李四', 20
union all
select 3, '王五', null;drop view if exists departments;
create temporary view departments as
select 10 as dept_id, '技術部' as dept_name, 'active' as status
union all
select 20, '市場部', 'inactive'
union all
select 30, '財務部', 'active';select *
from employees e
left join departments d on e.dept_id=d.dept_id and e.dept_id is not null;
實際執行中,物理執行引擎在不影響結果集的前提下也會進行一定的優化,主要優化邏輯就是將參與關聯的數據提早過濾,https://blog.csdn.net/atwdy/article/details/139125669 中對不同情況下的執行計劃進行過詳細的分析。