MySQL基礎05-關聯查詢

簡介

數據庫的關聯查詢可分爲5種,它們分別是:交叉連接(CROSS JOIN)、內連接(INNER JOIN)、外連接(LEFT JOIN/RIGHT JOIN)、聯合查詢(UNION與UNION ALL)、全連接(FULL JOIN)。

實驗表A:

mysql> select * from A;
+------+--------+
| id   | name   |
+------+--------+
|    1 | nosee  |
|    2 | chan   |
|    3 | cheese |
|    4 | xyz    |
+------+--------+
4 rows in set (0.00 sec)

實驗表B:

mysql> select * from B;
+------+------+
| id   | age  |
+------+------+
|    3 |   18 |
|    4 |   28 |
|    5 |   16 |
|    6 |  100 |
+------+------+
4 rows in set (0.00 sec)

一、交叉連接(CROSS JOIN) — 笛卡爾積

因爲沒有連接條件,所進行的表與表間的所有行的連接。,結果集會很大,沒有意義,很少使用。

語法:

SELECT * FROM A,B(,C...);
# 或者
SELECT * FROM A CROSS JOIN B (CROSS JOIN C ...);

特點:
①連接查詢沒有寫任何連接條件
②結果集中的總行數就是兩張表中總行數的乘積(笛卡爾積)

案例:

mysql> select * from A,B;   # 或 select * from A CROSS JOIN B;
+------+--------+------+------+
| id   | name   | id   | age  |
+------+--------+------+------+
|    1 | nosee  |    3 |   18 |
|    2 | chan   |    3 |   18 |
|    3 | cheese |    3 |   18 |
|    4 | xyz    |    3 |   18 |
|    1 | nosee  |    4 |   28 |
|    2 | chan   |    4 |   28 |
|    3 | cheese |    4 |   28 |
|    4 | xyz    |    4 |   28 |
|    1 | nosee  |    5 |   16 |
|    2 | chan   |    5 |   16 |
|    3 | cheese |    5 |   16 |
|    4 | xyz    |    5 |   16 |
|    1 | nosee  |    6 |  100 |
|    2 | chan   |    6 |  100 |
|    3 | cheese |    6 |  100 |
|    4 | xyz    |    6 |  100 |
+------+--------+------+------+
16 rows in set (0.00 sec)

二、內連接(INNER JOIN)

多表中同時符合某種條件的數據記錄的集合。 INNER JOIN可以縮寫爲JOIN。

語法:

SELECT * FROM A,B WHERE A.id = B.id;
# 或者
SELECT * FROM A INNER JOIN B ON A.id = B.id;

還可以使用using子句做條件,但相對用的比較少。

內連接分爲3類:
1)等值連接:ON A.id = B.id
2)不等值連接:ON A.id > B.id
3)自連接:SELECT * FROM A T1 INNER JOIN A T2 ON T1.id = T2.pid;

案例:

mysql> SELECT * FROM A JOIN B ON A.id = B.id;  # 或  SELECT * FROM A,B WHERE A.id = B.id;
+------+--------+------+------+
| id   | name   | id   | age  |
+------+--------+------+------+
|    3 | cheese |    3 |   18 |
|    4 | xyz    |    4 |   28 |
+------+--------+------+------+
2 rows in set (0.00 sec)

三、外連接(LEFT JOIN/RIGHT JOIN)

1、左外連接
LEFT OUTER JOIN,以左表爲主,先查詢出左表,按照ON後的關聯條件匹配右表,沒有匹配到的用NULL填充,可以簡寫成LEFT JOIN。

案例:

mysql> SELECT * FROM A LEFT JOIN B ON A.id = B.id;
+------+--------+------+------+
| id   | name   | id   | age  |
+------+--------+------+------+
|    1 | nosee  | NULL | NULL |
|    2 | chan   | NULL | NULL |
|    3 | cheese |    3 |   18 |
|    4 | xyz    |    4 |   28 |
+------+--------+------+------+
4 rows in set (0.00 sec)

2、右外連接
RIGHT OUTER JOIN,以右表爲主,先查詢出右表,按照ON後的關聯條件匹配左表,沒有匹配到的用NULL填充,可以簡寫成RIGHT JOIN。

案例:

mysql> SELECT * FROM A RIGHT JOIN B ON A.id = B.id;
+------+--------+------+------+
| id   | name   | id   | age  |
+------+--------+------+------+
|    3 | cheese |    3 |   18 |
|    4 | xyz    |    4 |   28 |
| NULL | NULL   |    5 |   16 |
| NULL | NULL   |    6 |  100 |
+------+--------+------+------+
4 rows in set (0.01 sec)

四、聯合查詢(UNION與UNION ALL)

語法:

SELECT * FROM A UNION SELECT * FROM B UNION ...

就是把多個結果集集中在一起,UNION前的結果爲基準,需要注意的是聯合查詢的列數要相等,相同的記錄行會合並。如果使用UNION ALL,則不會合並重復的記錄行。

案例:

mysql> SELECT * FROM A UNION SELECT * FROM B;
+------+--------+
| id   | name   |
+------+--------+
|    1 | nosee  |
|    2 | chan   |
|    3 | cheese |
|    4 | xyz    |
|    3 | 18     |
|    4 | 28     |
|    5 | 16     |
|    6 | 100    |
+------+--------+
8 rows in set (0.02 sec)

UNION與UNION ALL的區別:
1)對重複結果的處理:UNION會去掉重複記錄,UNION ALL不會;
2)對排序的處理:UNION會排序,UNION ALL只是簡單地將兩個結果集合並;
3)效率方面的區別:因爲UNION 會做去重和排序處理,因此效率比UNION ALL慢很多

五、全連接(FULL JOIN)

MySQL不支持全連接。

可以使用LEFT JOIN和UNION和RIGHT JOIN聯合使用來達到全連接的效果。

如:

SELECT * FROM A LEFT JOIN B ON A.id=B.id UNION 
SELECT * FROM A RIGHT JOIN B ON A.id=B.id

案例:

mysql> SELECT * FROM A LEFT JOIN B ON A.id=B.id UNION
    -> SELECT * FROM A RIGHT JOIN B ON A.id=B.id;
+------+--------+------+------+
| id   | name   | id   | age  |
+------+--------+------+------+
|    1 | nosee  | NULL | NULL |
|    2 | chan   | NULL | NULL |
|    3 | cheese |    3 |   18 |
|    4 | xyz    |    4 |   28 |
| NULL | NULL   |    5 |   16 |
| NULL | NULL   |    6 |  100 |
+------+--------+------+------+
6 rows in set (0.00 sec)

六、嵌套查詢–子查詢

用一條SQL語句的結果作爲另一條SQL語句的條件。

如:

SELECT * FROM A WHERE id IN (SELECT id FROM B);

特點(規範):
①子查詢必須放在小括號中
②子查詢一般放在比較操作符的右邊,以增強代碼可讀性
③子查詢(小括號裏的內容)可出現在幾乎所有的SELECT子句中(如:SELECT子句、FROM子句、WHERE子句、ORDER BY子句、HAVING子句……)

注意:一個子查詢會返回一個標量(就一個值)、一個行、一個列或一個表,這些子查詢稱之爲標量、行、列和表子查詢

案例:

mysql> SELECT * FROM A WHERE id IN (SELECT id FROM B);
+------+--------+
| id   | name   |
+------+--------+
|    3 | cheese |
|    4 | xyz    |
+------+--------+
2 rows in set (0.03 sec)

七、經典實例

1、爲了記錄足球比賽的結果,設計如下表:
1)參賽隊伍表:team

name type comment
teamID int 主鍵
teamName varchar(20) 隊伍名稱
mysql> select * from team;
+--------+----------+
| teamID | teamName |
+--------+----------+
|      1 | AA       |
|      2 | BB       |
|      3 | CC       |
+--------+----------+
3 rows in set (0.00 sec)

2)賽程表:match

name type comment
matchID int 主鍵
hostTeanID int 主隊ID
guestTeanID int 客隊ID
matchResult varchar(20) 比賽結果
matchTime date 比賽日期
mysql> select * from `match`;
+---------+------------+-------------+-------------+------------+
| matchID | hostTeamID | guestTeamID | matchResult | matchTime  |
+---------+------------+-------------+-------------+------------+
|       1 |          1 |           2 | 2:0         | 2006-06-05 |
|       2 |          2 |           3 | 1:2         | 2006-06-12 |
|       3 |          1 |           2 | 3:0         | 2006-06-23 |
+---------+------------+-------------+-------------+------------+
3 rows in set (0.00 sec)

要求:
其中,match賽程表中的hostTeamID與guestTeamID都和team表中的teamID關聯,查詢2006-6-1到2006-7-1之間舉行的所有比賽,並且用以下形式列出:拜仁 2:1 不菜 2006-6-22

分析:
主要的數據都在match表,基礎查詢如下:

select hostTeamID,matchResult,guestTeamID,matchTime from `match` 
where matchTime between "2006-6-1" and "2006-7-1";

關聯查詢:

# 相當於3表聯合查詢。
mysql> select t1.teamName,m.matchResult,t2.teamName,m.matchTime
    -> from `match` as m
    -> left join team as t1 on m.hostTeamID = t1.teamID
    -> left join team as t2 on m.guestTeamID = t2.teamID
    -> where m.matchTime between "2006-6-1" and "2006-7-1";
+----------+-------------+----------+------------+
| teamName | matchResult | teamName | matchTime  |
+----------+-------------+----------+------------+
| AA       | 2:0         | BB       | 2006-06-05 |
| BB       | 1:2         | CC       | 2006-06-12 |
| AA       | 3:0         | BB       | 2006-06-23 |
+----------+-------------+----------+------------+
3 rows in set (0.00 sec)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章