SELECT中的多表連接


MySQL多表連接查詢

連接(join):將一張表中的行按照某個條件(連接條件)和另一張表中的行連接起來形成一個新行的過程。

  根據連接查詢返回的結果,分3類:

    內連接(inner join)

    外連接(outer join)

    交叉連接(cross join)

  根據連接條件所使用的操作符,分2類:

    相等連接(使用等號操作符)

    不等連接(不使用等號操作符) 

標准的連接語法

注意:

  在連接查詢中,一個列可能出現在多張表中,為了避免引起歧義,通常在列名前面加上表名或表別名作為前綴(例: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)

 

1、內連接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。(相對用的會比較少) 

 

2、外連接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; 結果如上(用的是右連接的方式)

 


給連接查詢附加條件:

  1、寫在WHERE子句中

  2、使用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 連接條件;


 

3、交叉連接—笛卡爾積

  因為沒有連接條件,所進行的表與表間的所有行的連接。

特點:

  ①連接查詢沒有寫任何連接條件

  ②結果集中的總行數就是兩張表中總行數的乘積(笛卡爾積)

注意:在實際中,應該要避免產生笛卡爾積的連接,特別是對於大表

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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM