1.Inner Join 內連接
內連接InnerJoin基於連接謂詞將兩張表的列組合在一起,產生新的結果表
selct * from A inner join b on A.key=b.key
2.Left Outer Join左外連接(左連接)
select * from A left join B on A.key=B.key
(查出所有A表記錄,不能關聯B表的數據爲NULL)
select * from A left join B on A.key=B.key where B.key is null
(查出A表 中存在且B表中不存在的記錄,可以替換NOT IN,NOT IN 沒有使用索引,)
3、Right Outer Join 右外連接(右連接)
select * from A right join B on A.key=B.key
(查出所有B表記錄,不能關聯A表的數據爲NULL)
select * from A right join B on A.key=B.key where B.key is null
(查出B表 中存在且A表中不存在的記錄,可以替換NOT IN,NOT IN 沒有使用索引,)
4.Full Outer Join 全外連接
select * from A full join B on A.key=B.key
(查出所有AB表中的記錄,連接謂詞中沒有對應的用null進行填充)
select * from A full join B on A.key=B.key where a.key is null or b.key is null
(查出只存在AB表中的記錄,且過濾AB公共的部分)
mysql不支持full join,使用 union all 連接左右連接查詢
select * from A left join B on A.key=B.key union all select * from A right join B on A.key=B.key
5.Cross Join
交叉連接(cross join) ,笛卡爾連接(cartesian join) 或叉乘(Product),兩個表的乘積 A ×B,
select a.username,a.over,b.user_name,b.over from user1 a cross join user2 b
使用技巧
1、如何更新使用過濾條件中包括自身的表
update user1 set over=’情天大聖’ where user1.username in (select b,username from user1 a inner join user2 b on a.username=b.username );
報錯,優化如下:
update user1 a join (select b.username from user1 a inner join user2 b on a.username = b.username) b on a.username=b.username set a.over=’情天大聖’;
2.如何使用join 優化子查詢
select a.username ,a.over , (select over from user2 b where a.username=b.username) as over2 from user1 a;
優化:
select a.username,a.over,b.over as over2 from user1 a left join user2 b on a.username=b.username;
3.使用join優化聚合子查詢
select a.username,b.timestr,b.kills from user1 a join user_kills b on a.id=b.userid where b.kills = (select max(c.kills) from user_kills c where c.userid =b.userid)
優化:
select a.username,b.timestr,b.kills from user1 a join user_kills b on a.id=b.userid join user_kills c on c.userid=b.userid group by a.username.b.timestr,b.kills having b.kills =max(c.kills)
4.如何實現分組選擇 (應用場景,取出所有分類中點擊量最多的頭三條文章。。。)
查出取經四人組每人殺怪最多的頭兩天
對每個人分別執行下面的查詢:
select a.username,b.timestr,b.kills from user1 a join user_kills b on a.id = b.userid where username=”孫悟空” order by b.kills desc limit 2;
優化:
select d.username,c.timestr,kills from (select userid timestr,kills,(select count(*) from user_kills b where b.userid=a.userid and a.kills <= b.kills ) as cnt from user_kills a group by userid,timestr,kills ) c join user1 d on c.user_id =d.id where cnt<=2