SELECT中的多表鏈接

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)
相關文章
相關標籤/搜索