聯結的語法:
... from table1 inner|left|right join table2 on condition
內外聯結的區別: 內聯結將去除所有不符合條件condition的記錄,外聯結將保留部分不符合condition的記錄;
左聯結將保留左邊表table1的記錄,此時右邊表table2只返回符合condition的記錄。
1,join概述
... from table1 inner|left|right join table2 on condition
inner join : 內聯結,等值聯結,取得兩個表中符合condition的記錄id。
left join : 左聯結,取得table1的所有記錄(table1中condition中的字段可能為空),和table2符合condition的記錄,
right join : 右聯結,取得table2的所有的記錄(table2中condition中的字段可能為空),和table1符合condition的記錄,
2,Inner join
內聯結
select * from A inner join B on A.mobile = B.mobile and andCondition;
將會返回 A.id 不為空,B.id 不為空,且A.mobile = B.mobile 和符合 andCondition的數據
3,left join
select * from A left join B on A.mobile = B.mobile and andCondition;
將會返回A的所有記錄和 B.mobile = A.mobile的所有B的記錄。
如果想取得A表中不滿足condition的數據
select * from A
left join B on A.mobile = B.mobile
where B.is is null
得到
用left join 模擬 inner join
-> select * from A left join B on A.mobile = B.mobile where B.id is not null;
求A B 表中不符合condition條件的各自數據的集合
-> select * from A left join B on A.mobile = B.mobile where B.id is null
union
select * from A right join B on A.mobile = B.mobile where A.id is null
得到差異數據(不符合condition的兩個表的數據)
4,right join
-> select * from A right B on A.mobile = B.mobile ;
將得到B表的所有數據和A表中滿足condition的數據
5,cross join
交叉聯結,得到的是兩個表的乘積
在mysql中(僅限mysql) cross join 和 inner join 的表現是一樣的。在不指定on條件得到的都是笛卡爾積。
所以下面的三個語句效果一樣
->...from A inner join B
->...from A cross join B
->...from A join B
6,full join
-> select * from A left join B on A.mobile = B.mobile;
union
select * from A right join B on A.mobile = B.mobile;
得到
7,性能優化
(1)顯示inner join 和 隱式inner join
顯示 --> select * from A inner join B on A.mobile = B.mobile;
隱式 --> select * from A inner join B where A.mobile = B.mobile;
10萬數據的查詢用時幾乎相等。
(2)left join / right join 和 inner join
盡量用inner join 避免 外聯結 和 null
在使用外聯結的時候,如 -> select * from A left join B on A.mobile = B.mobile where whereCondition;
如果B中沒有滿足on condition的條件,則會產生一行所有列為null的數據。
在 on condition 匹配階段,where 條件不會被使用。在on condition結束后,where將會被使用,where條件將會從滿足on condition的數據中再檢索一次。
所以,在使用外聯結市,我們要盡量給出盡可能多的匹配滿足條件(即 on condition),減少where字句的檢索。
不建議sql -> select * from A
left join B on A.mobile = B.mobile
left join C on A.name = C.name
where A.status = 1 and C.status = 1
建議的sql -> select * from A
left join B on A.mobile = B.mobile and A.status = 1
left join C on A.name = C.name and C.status = 1
盡量滿足on condition,而少使用where的條件。
(3)on 條件 和 where 條件的不同
->select * from A left join B on A.mobile = B.mobile on A.name is not null;
將會返回A表的所有記錄 和 B表中滿足 (A.mobile = B.mobile on A.name is not null) 的記錄;
->select * from A left join B on A.mobile = B.mobile where A.name is not null;
將會返回A表中所有記錄 和 B表中滿足 (A.mobile = B.mobile)的記錄,然后 再通過where條件(A.name is not null)對結果進行篩選。
第一條sql語句返回的結果集條數 >= 第二條sql
(4)盡量避免子查詢,而用join