新聞中心
前面所講的查詢語句都是針對一個(gè)表的,但是在關(guān)系型數(shù)據(jù)庫中,表與表之間是有聯(lián)系的,所以在實(shí)際應(yīng)用中,經(jīng)常使用多表查詢。多表查詢就是同時(shí)查詢兩個(gè)或兩個(gè)以上的表。

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、川匯ssl等。為近千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的川匯網(wǎng)站制作公司
在 MySQL 中,多表查詢主要有交叉連接、內(nèi)連接和外連接。由于篇幅有限,本節(jié)主要講解交叉連接查詢。內(nèi)連接和外連接將在《 MySQL內(nèi)連接》和《 MySQL外連接》中講解。
交叉連接(CROSS JOIN)一般用來返回連接表的笛卡爾積。
本節(jié)的末尾介紹了笛卡爾積,不了解笛卡爾積的讀者可以先閱讀文章末尾部分,然后再繼續(xù)學(xué)習(xí)交叉連接。
交叉連接的語法格式如下:
SELECT <字段名> FROM <表1> CROSS JOIN <表2> [WHERE子句]
或
SELECT <字段名> FROM <表1>, <表2> [WHERE子句]
語法說明如下:
- 字段名:需要查詢的字段名稱。
- <表1><表2>:需要交叉連接的表名。
- WHERE 子句:用來設(shè)置交叉連接的查詢條件。
注意:多個(gè)表交叉連接時(shí),在 FROM 后連續(xù)使用 CROSS JOIN 或, 即可。以上兩種語法的返回結(jié)果是相同的,但是第一種語法才是官方建議的標(biāo)準(zhǔn)寫法。
當(dāng)連接的表之間沒有關(guān)系時(shí),我們會(huì)省略掉 WHERE 子句,這時(shí)返回結(jié)果就是兩個(gè)表的笛卡爾積,返回結(jié)果數(shù)量就是兩個(gè)表的數(shù)據(jù)行相乘。需要注意的是,如果每個(gè)表有 1000 行,那么返回結(jié)果的數(shù)量就有 1000×1000 = 1000000 行,數(shù)據(jù)量是非常巨大的。
交叉連接可以查詢兩個(gè)或兩個(gè)以上的表,為了讓讀者更好的理解,下面先講解兩個(gè)表的交叉連接查詢。
例 1
查詢學(xué)生信息表和科目信息表,并得到一個(gè)笛卡爾積。
為了方便觀察學(xué)生信息表和科目表交叉連接后的運(yùn)行結(jié)果,我們先分別查詢出這兩個(gè)表的數(shù)據(jù),再進(jìn)行交叉連接查詢。
1)查詢 tb_students_info 表中的數(shù)據(jù),SQL 語句和運(yùn)行結(jié)果如下:
mysql> SELECT * FROM tb_students_info; +----+--------+------+------+--------+-----------+ | id | name | age | sex | height | course_id | +----+--------+------+------+--------+-----------+ | 1 | Dany | 25 | 男 | 160 | 1 | | 2 | Green | 23 | 男 | 158 | 2 | | 3 | Henry | 23 | 女 | 185 | 1 | | 4 | Jane | 22 | 男 | 162 | 3 | | 5 | Jim | 24 | 女 | 175 | 2 | | 6 | John | 21 | 女 | 172 | 4 | | 7 | Lily | 22 | 男 | 165 | 4 | | 8 | Susan | 23 | 男 | 170 | 5 | | 9 | Thomas | 22 | 女 | 178 | 5 | | 10 | Tom | 23 | 女 | 165 | 5 | +----+--------+------+------+--------+-----------+ 10 rows in set (0.00 sec)
2)查詢 tb_course 表中的數(shù)據(jù),SQL 語句和運(yùn)行結(jié)果如下:
mysql> SELECT * FROM tb_course; +----+-------------+ | id | course_name | +----+-------------+ | 1 | Java | | 2 | MySQL | | 3 | Python | | 4 | Go | | 5 | C++ | +----+-------------+ 5 rows in set (0.00 sec)
3)使用 CROSS JOIN 查詢出兩張表中的笛卡爾積,SQL 語句和運(yùn)行結(jié)果如下:
mysql> SELECT * FROM tb_course CROSS JOIN tb_students_info; +----+-------------+----+--------+------+------+--------+-----------+ | id | course_name | id | name | age | sex | height | course_id | +----+-------------+----+--------+------+------+--------+-----------+ | 1 | Java | 1 | Dany | 25 | 男 | 160 | 1 | | 2 | MySQL | 1 | Dany | 25 | 男 | 160 | 1 | | 3 | Python | 1 | Dany | 25 | 男 | 160 | 1 | | 4 | Go | 1 | Dany | 25 | 男 | 160 | 1 | | 5 | C++ | 1 | Dany | 25 | 男 | 160 | 1 | | 1 | Java | 2 | Green | 23 | 男 | 158 | 2 | | 2 | MySQL | 2 | Green | 23 | 男 | 158 | 2 | | 3 | Python | 2 | Green | 23 | 男 | 158 | 2 | | 4 | Go | 2 | Green | 23 | 男 | 158 | 2 | | 5 | C++ | 2 | Green | 23 | 男 | 158 | 2 | | 1 | Java | 3 | Henry | 23 | 女 | 185 | 1 | | 2 | MySQL | 3 | Henry | 23 | 女 | 185 | 1 | | 3 | Python | 3 | Henry | 23 | 女 | 185 | 1 | | 4 | Go | 3 | Henry | 23 | 女 | 185 | 1 | | 5 | C++ | 3 | Henry | 23 | 女 | 185 | 1 | | 1 | Java | 4 | Jane | 22 | 男 | 162 | 3 | | 2 | MySQL | 4 | Jane | 22 | 男 | 162 | 3 | | 3 | Python | 4 | Jane | 22 | 男 | 162 | 3 | | 4 | Go | 4 | Jane | 22 | 男 | 162 | 3 | | 5 | C++ | 4 | Jane | 22 | 男 | 162 | 3 | | 1 | Java | 5 | Jim | 24 | 女 | 175 | 2 | | 2 | MySQL | 5 | Jim | 24 | 女 | 175 | 2 | | 3 | Python | 5 | Jim | 24 | 女 | 175 | 2 | | 4 | Go | 5 | Jim | 24 | 女 | 175 | 2 | | 5 | C++ | 5 | Jim | 24 | 女 | 175 | 2 | | 1 | Java | 6 | John | 21 | 女 | 172 | 4 | | 2 | MySQL | 6 | John | 21 | 女 | 172 | 4 | | 3 | Python | 6 | John | 21 | 女 | 172 | 4 | | 4 | Go | 6 | John | 21 | 女 | 172 | 4 | | 5 | C++ | 6 | John | 21 | 女 | 172 | 4 | | 1 | Java | 7 | Lily | 22 | 男 | 165 | 4 | | 2 | MySQL | 7 | Lily | 22 | 男 | 165 | 4 | | 3 | Python | 7 | Lily | 22 | 男 | 165 | 4 | | 4 | Go | 7 | Lily | 22 | 男 | 165 | 4 | | 5 | C++ | 7 | Lily | 22 | 男 | 165 | 4 | | 1 | Java | 8 | Susan | 23 | 男 | 170 | 5 | | 2 | MySQL | 8 | Susan | 23 | 男 | 170 | 5 | | 3 | Python | 8 | Susan | 23 | 男 | 170 | 5 | | 4 | Go | 8 | Susan | 23 | 男 | 170 | 5 | | 5 | C++ | 8 | Susan | 23 | 男 | 170 | 5 | | 1 | Java | 9 | Thomas | 22 | 女 | 178 | 5 | | 2 | MySQL | 9 | Thomas | 22 | 女 | 178 | 5 | | 3 | Python | 9 | Thomas | 22 | 女 | 178 | 5 | | 4 | Go | 9 | Thomas | 22 | 女 | 178 | 5 | | 5 | C++ | 9 | Thomas | 22 | 女 | 178 | 5 | | 1 | Java | 10 | Tom | 23 | 女 | 165 | 5 | | 2 | MySQL | 10 | Tom | 23 | 女 | 165 | 5 | | 3 | Python | 10 | Tom | 23 | 女 | 165 | 5 | | 4 | Go | 10 | Tom | 23 | 女 | 165 | 5 | | 5 | C++ | 10 | Tom | 23 | 女 | 165 | 5 | +----+-------------+----+--------+------+------+--------+-----------+ 50 rows in set (0.00 sec)
由運(yùn)行結(jié)果可以看出,tb_course 和 tb_students_info 表交叉連接查詢后,返回了 50 條記錄??梢韵胂?,當(dāng)表中的數(shù)據(jù)較多時(shí),得到的運(yùn)行結(jié)果會(huì)非常長,而且得到的運(yùn)行結(jié)果也沒太大的意義。所以,通過交叉連接的方式進(jìn)行多表查詢的這種方法并不常用,我們應(yīng)該盡量避免這種查詢。
例 2
查詢 tb_course 表中的 id 字段和 tb_students_info 表中的 course_id 字段相等的內(nèi)容, SQL 語句和運(yùn)行結(jié)果如下:
mysql> SELECT * FROM tb_course CROSS JOIN tb_students_info
-> WHERE tb_students_info.course_id = tb_course.id;
+----+-------------+----+--------+------+------+--------+-----------+
| id | course_name | id | name | age | sex | height | course_id |
+----+-------------+----+--------+------+------+--------+-----------+
| 1 | Java | 1 | Dany | 25 | 男 | 160 | 1 |
| 2 | MySQL | 2 | Green | 23 | 男 | 158 | 2 |
| 1 | Java | 3 | Henry | 23 | 女 | 185 | 1 |
| 3 | Python | 4 | Jane | 22 | 男 | 162 | 3 |
| 2 | MySQL | 5 | Jim | 24 | 女 | 175 | 2 |
| 4 | Go | 6 | John | 21 | 女 | 172 | 4 |
| 4 | Go | 7 | Lily | 22 | 男 | 165 | 4 |
| 5 | C++ | 8 | Susan | 23 | 男 | 170 | 5 |
| 5 | C++ | 9 | Thomas | 22 | 女 | 178 | 5 |
| 5 | C++ | 10 | Tom | 23 | 女 | 165 | 5 |
+----+-------------+----+--------+------+------+--------+-----------+
10 rows in set (0.01 sec)如果在交叉連接時(shí)使用 WHERE 子句,MySQL 會(huì)先生成兩個(gè)表的笛卡爾積,然后再選擇滿足 WHERE 條件的記錄。因此,表的數(shù)量較多時(shí),交叉連接會(huì)非常非常慢。一般情況下不建議使用交叉連接。
在 MySQL 中,多表查詢一般使用內(nèi)連接和外連接,它們的效率要高于交叉連接。請猛擊《 MySQL內(nèi)連接》和《 MySQL外連接》閱讀學(xué)習(xí) MySQL 中的內(nèi)連接和外連接。
笛卡爾積
笛卡爾積(Cartesian product)是指兩個(gè)集合 X 和 Y 的乘積。
例如,有 A 和 B 兩個(gè)集合,它們的值如下:
A = {1,2}
B = {3,4,5}
集合 A×B 和 B×A 的結(jié)果集分別表示為:
A×B={(1,3), (1,4), (1,5), (2,3), (2,4), (2,5) };
B×A={(3,1), (3,2), (4,1), (4,2), (5,1), (5,2) };
以上 A×B 和 B×A 的結(jié)果就叫做兩個(gè)集合的笛卡爾積。
并且,從以上結(jié)果我們可以看出:
- 兩個(gè)集合相乘,不滿足交換率,即 A×B≠B×A。
- A 集合和 B 集合的笛卡爾積是 A 集合的元素個(gè)數(shù) × B 集合的元素個(gè)數(shù)。
多表查詢遵循的算法就是以上提到的笛卡爾積,表與表之間的連接可以看成是在做乘法運(yùn)算。在實(shí)際應(yīng)用中,應(yīng)避免使用笛卡爾積,因?yàn)榈芽柗e中容易存在大量的不合理數(shù)據(jù),簡單來說就是容易導(dǎo)致查詢結(jié)果重復(fù)、混亂。
當(dāng)前文章:創(chuàng)新互聯(lián)數(shù)據(jù)庫教程:MySQLCROSSJOIN:交叉連接
文章轉(zhuǎn)載:http://fisionsoft.com.cn/article/cdhcdcg.html


咨詢
建站咨詢
