MySQL多表鏈接查詢mysql
鏈接(join):將一張表中的行按照某個條件(鏈接條件)和另外一張表中的行鏈接起來造成一個新行的過程。linux
根據鏈接查詢返回的結果,分3類:sql
內鏈接(inner join)數據庫
外鏈接(outer join)oop
交叉鏈接(cross join)spa
根據鏈接條件所使用的操做符,分2類:code
相等鏈接(使用等號操做符)blog
不等鏈接(不使用等號操做符) 內存
標準的鏈接語法:hadoop
注意:
在鏈接查詢中,一個列可能出如今多張表中,爲了不引發歧義,一般在列名前面加上表名或表別名做爲前綴(例:s.sid、x.sid)---使用表別名做爲前綴,能夠使得SQL代碼較短,使用的內存更少(例:stu s,xuanke as x)。
搭建環境:模擬選課
mysql> select * from stu; +------+--------+---------+
| sid | sname | sphonum |
+------+--------+---------+
| 1 | 張三 | 110 |
| 2 | 李四 | 120 |
| 3 | 王五 | 130 |
+------+--------+---------+
3 rows in set (0.00 sec) mysql> select * from tea; +------+-----------+---------+
| tid | tname | tphonum |
+------+-----------+---------+
| 1113 | 相老師 | 1111 |
| 1114 | 馮老師 | 1112 |
+------+-----------+---------+
2 rows in set (0.00 sec) mysql> select * from course; +------+--------+
| cid | cname |
+------+--------+
| 1 | linux |
| 2 | mysql |
| 3 | hadoop |
+------+--------+
3 rows in set (0.00 sec) mysql> select * from xuanke; +------+------+------+--------+
| sid | tid | cid | xuefen |
+------+------+------+--------+
| 1 | 1113 | 2 | 2 |
| 1 | 1114 | 1 | 4 |
| 1 | 1113 | 3 | 6 |
| 2 | 1113 | 2 | 2 |
| 2 | 1114 | 1 | 2 |
| 2 | 1113 | 3 | 2 |
+------+------+------+--------+
6 rows in set (0.00 sec)
一、內鏈接inner join
只返回兩張表中全部知足鏈接條件的行,即便用比較運算符根據每一個表中共有的列的值匹配兩個表中的行。(inner關鍵字是可省略的)
①傳統的鏈接寫法:
在FROM子句中列出全部要鏈接的表的名字(進行表別名),以逗號分隔;
鏈接條件寫在WHERE子句中;
注意:一旦給表定義了別名,那麼原始的表名就不能在出如今該語句的其它子句中
mysql> select s.sname,c.cname,t.tname,x.xuefen -> from stu s,tea t,course c,xuanke x -> where s.sid=x.sid and t.tid=x.tid and c.cid=x.cid; +--------+--------+-----------+--------+
| sname | cname | tname | xuefen |
+--------+--------+-----------+--------+
| 張三 | linux | 馮老師 | 4 |
| 李四 | linux | 馮老師 | 2 |
| 張三 | mysql | 相老師 | 2 |
| 李四 | mysql | 相老師 | 2 |
| 張三 | hadoop | 相老師 | 6 |
| 李四 | hadoop | 相老師 | 2 |
+--------+--------+-----------+--------+
6 rows in set (0.08 sec)
②使用on子句(經常使用):筆者比較喜歡的方法,由於以爲結構清晰明瞭。
mysql> select s.sname,t.tname,c.cname,x.xuefen -> from stu s -> join xuanke x -> on s.sid=x.sid -> join tea t -> on x.tid=t.tid -> join course c -> on c.cid=x.cid; 結果如上……
表之間的關係以JOIN指定,ON的條件與WHERE條件相同。
③使用using子句
mysql> select s.sname,t.tname,c.cname,x.xuefen -> from stu s -> join xuanke x -> using(sid) -> join tea t -> using(tid) -> join course c -> using(cid);
結果如上……
表之間的關係以join指定,using(鏈接列)進行鏈接匹配,相似於on。(相對用的會比較少)
二、外鏈接outer join
使用外鏈接不但返回符合鏈接和查詢條件的數據行,還返回不符合條件的一些行。
在MySQL數據庫中外鏈接分兩類(不支持全外鏈接):
左外鏈接、右外鏈接。(outer關鍵字可省略)。
共同點:都返回符合鏈接條件和查詢條件(即:內鏈接)的數據行
不一樣點:
①左外鏈接還返回左表中不符合鏈接條件,但符合查詢條件的數據行。(所謂左表,就是寫在left join關鍵字左邊的表)
②右外鏈接還返回右表中不符合鏈接條件,但符合查詢條件的數據行。(所謂右表,就是寫在right join關鍵字右邊的表)
mysql> select s.sname,x.xuefen -> from stu s -> left join xuanke x -> on s.sid=x.sid; +--------+--------+
| sname | xuefen |
+--------+--------+
| 張三 | 2 |
| 張三 | 4 |
| 張三 | 6 |
| 李四 | 2 |
| 李四 | 2 |
| 李四 | 2 |
| 王五 | NULL |
+--------+--------+
7 rows in set (0.00 sec)
解析:stu表是左表,xuanke表是右表:left join是左鏈接,stu表中」王五」沒有選課,在xueke表中沒有數據行,不符合鏈接條件,返回符合查詢條件的數據行,因此xuefen爲null。
mysql> select s.sname,x.xuefen -> from xuanke x -> right join stu s -> on x.sid=s.sid; 結果如上(用的是右鏈接的方式)
給鏈接查詢附加條件:
一、寫在WHERE子句中
二、使用AND和鏈接條件寫在一塊兒
!!!可是:
對於內鏈接,兩種寫法結果相同;
對於外鏈接,兩種寫法結果不一樣。
mysql> select s.sname,x.xuefen -> from stu s -> left join xuanke x -> on x.sid=s.sid -> where sname='張三'; +--------+--------+
| sname | xuefen |
+--------+--------+
| 張三 | 2 |
| 張三 | 4 |
| 張三 | 6 |
+--------+--------+
3 rows in set (0.01 sec) mysql> select s.sname,x.xuefen -> from (select * from stu where sname='張三') s -> left join xuanke x -> on x.sid=s.sid; +--------+--------+
| sname | xuefen |
+--------+--------+
| 張三 | 2 |
| 張三 | 4 |
| 張三 | 6 |
+--------+--------+
3 rows in set (0.00 sec)
①先鏈接後過濾
select ……from ……
left join ……
on 鏈接條件
where 過濾條件;
②先過濾後鏈接
select ……from (select ……from ……where 過濾條件)
left join ……
on 鏈接條件;
三、交叉鏈接—笛卡爾積
由於沒有鏈接條件,所進行的表與表間的全部行的鏈接。
特色:
①鏈接查詢沒有寫任何鏈接條件
②結果集中的總行數就是兩張表中總行數的乘積(笛卡爾積)
注意:在實際中,應該要避免產生笛卡爾積的鏈接,特別是對於大表
mysql> select * from stu,tea,course,xuanke; …… …… 108 rows in set (0.00 sec)
如果想專門產生笛卡爾積,能夠使用交叉鏈接
mysql> select *
-> from stu -> crosss join tea; +------+--------+---------+------+-----------+---------+
| sid | sname | sphonum | tid | tname | tphonum |
+------+--------+---------+------+-----------+---------+
| 1 | 張三 | 110 | 1113 | 相老師 | 1111 |
| 1 | 張三 | 110 | 1114 | 馮老師 | 1112 |
| 2 | 李四 | 120 | 1113 | 相老師 | 1111 |
| 2 | 李四 | 120 | 1114 | 馮老師 | 1112 |
| 3 | 王五 | 130 | 1113 | 相老師 | 1111 |
| 3 | 王五 | 130 | 1114 | 馮老師 | 1112 |
+------+--------+---------+------+-----------+---------+
6 rows in set (0.00 sec)