JOIN的含義就如英文單詞「join」同樣,鏈接兩張表,語法以下所示:html
SELECT * FROM A INNER|LEFT|RIGHT JOIN B ON conditionmysql
JOIN 按照功能大體分爲以下三類:sql
INNER JOIN(內鏈接,或等值鏈接):取得兩個表中存在鏈接匹配關係的記錄。數據庫
LEFT JOIN(左鏈接):取得左表(A)徹底記錄,便是右表(B)並沒有對應匹配記錄。app
RIGHT JOIN(右鏈接):與 LEFT JOIN 相反,取得右表(B)徹底記錄,便是左表(A)並沒有匹配對應記錄。ide
注意: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),spa 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;
若是想只從左表(A)中產生一套記錄,但不包含右表(B)的記錄,能夠經過設置where語句來執行,以下:
- 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'; |
結果: |
結果: |