JOIN的含義就如英文單詞“join”一樣,連接兩張表,語法如下所示:
SELECT * FROM A INNER|LEFT|RIGHT JOIN B ON condition
JOIN 按照功能大致分為如下三類:
INNER JOIN(內連接,或等值連接):取得兩個表中存在連接匹配關系的記錄。
LEFT JOIN(左連接):取得左表(A)完全記錄,即是右表(B)並無對應匹配記錄。
RIGHT JOIN(右連接):與 LEFT JOIN 相反,取得右表(B)完全記錄,即是左表(A)並無匹配對應記錄。
注意:mysql不支持Full join,不過可以通過UNION 關鍵字來合並 LEFT JOIN 與 RIGHT JOIN來模擬FULL join.
0.准備數據
表
|
表數據
|
命令
|
|
---|---|---|---|
blog 記錄文章名與文章類型 |
|
create table blog( id INT primary key auto_increment, title_name varchar(40), title_type int ); insert into blog values(0,'aa',1),(0,'bb',2),(0,'cc',3),(0,'dd',4),(0,'ee',3),(0,'ff',2),(0,'gg',default),(0,'hh',6); |
|
blog_type 記錄文章類型 |
|
create table blog_type( id INT primary key auto_increment, name varchar(40) ); insert into blog_type values(0,'C'),(0,'PYTHON'),(0,'JAVA'),(0,'HTML'),(0,'C++'); |
1.內連接:INNER JOIN
內連接INNER JOIN/JOIN是最常用的連接操作。從數學的角度講就是求兩個表的交集:
- select * from blog inner join blog_type on blog.title_type=blog_type.id;
- select * from blog join blog_type on blog.title_type=blog_type.id;
- select * from blog,blog_type where blog.title_type=blog_type.id;
輸出結果:
2.左連接:LEFT JOIN
左連接LEFT JOIN的含義就是求兩個表的交集外加左表剩下的數據,左連接從左表(A)產生一套完整的記錄,與匹配的記錄(右表(B)) .如果沒有匹配,右側將包含null。
- select * from blog left join blog_type on blog.title_type=blog_type.id;
- select * from blog left join blog_type on blog.title_type=blog_type.id where blog_type.id is null;
3.右連接:RIGHT JOIN
同理右連接RIGHT JOIN就是求兩個表的交集外加右表剩下的數據。
select * from blog right join blog_type on blog.title_type=blog_type.id;
4.USING子句
MySQL中連接SQL語句中,ON子句的語法格式為:table1.column_name = table2.column_name。當模式設計對聯接表的列采用了相同的命名樣式時,就可以使用 USING 語法來簡化 ON 語法,格式為:USING(column_name)。 所以,USING的功能相當於ON,區別在於USING指定一個屬性名用於連接兩個表,而ON指定一個條件。另外,SELECT *時,USING會去除USING指定的列,而ON不會。實例如下。
create table blog_type_1 as select * from blog_type;
alter table blog_type drop id;alter table blog_type add title_type int not null primary key auto_increment first;
mysql
|
結果
|
其他
|
---|---|---|
select * from blog inner join blog_type on blog.title_type=blog_type.title_type; |
|
|
select * from blog join blog_type using(title_type); |
|
USING會去除USING指定的列 |
join中改善性能的一些注意點:來自https://www.cnblogs.com/fudashi/p/7506877.html
- 小表驅動大表能夠減少內循環的次數從而提高連接效率。
- 在被驅動表建立索引能夠提高連接效率
- 優先選擇驅動表的屬性進行排序能夠提高連接效率
擴展知識點:
0.表別名的使用:
對單表做簡單的別名查詢通常是無意義的。一般是對一個表要當作多個表來操作,或者是對多個表進行操作時,才設置表別名。
1.group by的用法
2.子查詢
嵌套在其它查詢中的查詢稱之為子查詢或內部查詢,包含子查詢的查詢稱之為主查詢或外部查詢
1)不相關子查詢
內部查詢的執行獨立於外部查詢,內部查詢僅執行一次,執行完畢后將結果作為外部查詢的條件使用
一般在子查詢中,程序先運行在嵌套在最內層的語句,再運行外層。因此在寫子查詢語句時,可以先測試下內層的子查詢語句是否輸出了想要的內容,再一層層往外測試,增加子查詢正確率。否則多層的嵌套使語句可讀性很低。
舉栗:想要從數據庫中獲取文章類型是Python的文章列表
A
|
B
|
---|---|
|
|
分步執行:
獲取id: select id from blog_type where name='PYTHON';---->id=2
獲取文章列表:select title_name from blog where title_type=2;-→title name=(bb,ff)
聯合查詢:
子查詢的方式:select title_name from blog where title_type=(select id from blog_type where name='PYTHON');
聯表查詢的方式:select title_name from blog A join blog_type B on A.title_type=B.id where B.name='PYTHON';
2)相關子查詢
內部查詢的執行依賴於外部查詢的數據,外部查詢每執行一次,內部查詢也會執行一次。每一次都是外部查詢先執行,取出外部查詢表中的一個元組,將當前元組中的數據傳遞給內部查詢,然后執行內部查詢。
根據內部查詢執行的結果,判斷當前元組是否滿足外部查詢中的where條件,若滿足則當前元組是符合要求的記錄,否則不符合要求。然后,外部查詢繼續取出下一個元組數據,執行上述的操作,直到全部元組均被處理完畢。
舉栗:從歷史最好記錄的表中獲取各個指標最新時間的值
表數據:
藍色框框中的fr指標數據是重復的,預期想要獲取各個指標最新時間的指標值
相關子查詢
|
聯表查詢
|
---|---|
select * from test_best_history_for_storm_largescale t where date =(select max(date) from test_best_history_for_storm_largescale where fr=t.fr and area="largescale_fuji") and area="largescale_fuji"; | select * from test_best_history_for_storm_largescale A join (select max(date) date,fr from test_best_history_for_storm_largescale where area='largescale_fuji' group by fr)B on A.date=B.date and A.fr=B.fr and A.area='largescale_fuji'; |
結果:
|
結果:
|