前言
連接查詢包括合并、內(nèi)連接、外連接和交叉連接,如果涉及多表查詢,了解這些連接的特點(diǎn)很重要。
只有真正了解它們之間的區(qū)別,才能正確使用。
一、Union
UNION 操作符用于合并兩個(gè)或多個(gè) SELECT 語句的結(jié)果集。
UNION 運(yùn)算符通過組合其他兩個(gè)結(jié)果表(例如 TABLE1 和 TABLE2)并消去表中任何重復(fù)行而派生出一個(gè)結(jié)果表。
當(dāng) ALL 隨 UNION 一起使用時(shí)(即 UNION ALL),不消除重復(fù)行。兩種情況下,派生表的每一行不是來自 TABLE1 就是來自 TABLE2。
注意:使用UNION時(shí),兩張表查詢的結(jié)果有相同數(shù)量的列、列類型相似。
學(xué)生表信息(Students):
| ID | Name | Age | City | MajorID |
|---|---|---|---|---|
| 1 | Jack | 12 | Beijing | 10 |
| 2 | Lucy | 13 | Shanghai | 11 |
教師表信息(Teachers):
| ID | Name |
|---|---|
| 1 | Jack |
| 2 | Mrs Lee |
1)基本UNION查詢,查詢學(xué)校教師、學(xué)生的總的信息表,包括ID和姓名
SELECT ID,Name FROM Students
UNION
SELECT ID,Name FROM Teachers
查詢結(jié)果:
| ID | Name |
|---|---|
| 1 | Jack |
| 2 | Lucy |
| 2 | Mrs Lee |
2)查詢教師學(xué)生全部姓名
因?yàn)閁NION只會(huì)選擇不同的值,如果學(xué)生中和教師中有重名的情況,這就需要UNION ALL
SELECT Name FROM Students
UNION ALL
SELECT Name FROM Teachers
查詢結(jié)果:
| ID | Name |
|---|---|
| 1 | Jack |
| 2 | Lucy |
| 1 | Jack |
| 2 | Mrs Lee |
二、INNER JOIN(內(nèi)連接)
INNER JOIN(內(nèi)連接),也成為自然連接
作用:根據(jù)兩個(gè)或多個(gè)表中的列之間的關(guān)系,從這些表中查詢數(shù)據(jù)。
注意??: 內(nèi)連接是從結(jié)果中刪除其他被連接表中沒有匹配行的所有行,所以內(nèi)連接可能會(huì)丟失信息。
重點(diǎn):內(nèi)連接,只查匹配行。
語法:(INNER可省略)
SELECT fieldlist
FROM table1 [INNER] join table2
ON table1.column=table2.column
學(xué)生表信息(Students):
| ID | Name | Age | City | MajorID |
|---|---|---|---|---|
| 1 | Jack | 12 | Beijing | 10 |
| 2 | Lucy | 13 | Shanghai | 11 |
專業(yè)信息表(Majors):
| ID | Name |
|---|---|
| 10 | English |
| 15 | Computer |
實(shí)例:查詢學(xué)生信息,包括ID,姓名、專業(yè)名稱
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students INNER JOIN Majors
ON Students.MajorID = Majors.ID
查詢結(jié)果:
| ID | Name | MajorName |
|---|---|---|
| 1 | Jack | English |
根據(jù)結(jié)果可以清晰看到,確實(shí)只有匹配的行。學(xué)生Lucy的信息丟失了。
三、外連接
與內(nèi)連接相比,即使沒有匹配行,也會(huì)返回一個(gè)表的全集。
外連接分為三種:左外連接,右外連接,全外連接。
對應(yīng)SQL:LEFT/RIGHT/FULL OUTER JOIN。
通常我們省略outer 這個(gè)關(guān)鍵字。寫成:LEFT/RIGHT/FULL JOIN。
重點(diǎn):至少有一方保留全集,沒有匹配行用NULL代替。
1、LEFT JOIN (左連接)
結(jié)果集保留左表的所有行,但只包含第二個(gè)表與第一表匹配的行。第二個(gè)表相應(yīng)的空行被放入NULL值。
依然沿用內(nèi)鏈接的例子:
(1)使用左連接查詢學(xué)生的信息,其中包括學(xué)生ID,學(xué)生姓名和專業(yè)名稱。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students LEFT JOIN Majors
ON Students.MajorID = Majors.ID
查詢結(jié)果:
| ID | Name | MajorName |
|---|---|---|
| 1 | Jack | English |
| 2 | Lucy | Null |
通過結(jié)果,我們可以看到左連接包含了第一張表的所有信息,在第二張表中如果沒有匹配項(xiàng),則用NULL代替。
2、RIGHT JOIN (右連接)
右外連接保留了第二個(gè)表的所有行,但只包含第一個(gè)表與第二個(gè)表匹配的行。第一個(gè)表相應(yīng)空行被入NULL值。
右連接與左連接思想類似。只是第二張保留全集,如果第一張表中沒有匹配項(xiàng),用NULL代替
依然沿用內(nèi)鏈接的例子,只是改為右連接
(2)使用右連接查詢學(xué)生的信息,其中包括學(xué)生ID,學(xué)生姓名和專業(yè)名稱
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students RIGHT JOIN Majors
ON Students.MajorID = Majors.ID
查詢結(jié)果:
| ID | Name | MajorName |
|---|---|---|
| 1 | Jack | English |
| Null | Null | Computer |
通過結(jié)果可以看到,包含了第二張表Majors的全集,Computer在Students表中沒有匹配項(xiàng),就用NULL代替。
3、FULL JOIN (全連接)
會(huì)把兩個(gè)表所有的行都顯示在結(jié)果表中
3)使用全連接查詢學(xué)生的信息,其中包括學(xué)生ID,學(xué)生姓名和專業(yè)名稱。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students FULL JOIN Majors
ON Students.MajorID = Majors.ID
查詢結(jié)果:
| ID | Name | MajorName |
|---|---|---|
| 1 | Jack | English |
| 2 | Lucy | Null |
| Null | Null | Computer |
包含了兩張表的所有記錄,沒有記錄丟失,沒有匹配的行用NULL代替。
4、CROSS JOIN(交叉連接)
交叉連接。交叉連接返回左表中的所有行,左表中的每一行與右表中的所有行組合。交叉連接也稱作笛卡爾積。
簡單查詢兩張表組合,這是求笛卡兒積,效率最低。
笛卡兒積:笛卡爾乘積,也叫直積。假設(shè)集合A={a,b},集合B={0,1,2},則兩個(gè)集合的笛卡爾積為{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}??梢詳U(kuò)展到多個(gè)集合的情況。類似的例子有,如果A表示某學(xué)校學(xué)生的集合,B表示該學(xué)校所有課程的集合,則A與B的笛卡爾積表示所有可能的選課情況。
4)交叉連接查詢學(xué)生的信息,其中包括學(xué)生ID,學(xué)生姓名和專業(yè)名稱。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students CROSS JOIN Majors
查詢結(jié)果:
| ID | Name | MajorName |
|---|---|---|
| 1 | Jack | English |
| 2 | Lucy | English |
| 1 | Jack | Computer |
| 2 | Lucy | Computer |
5)查詢多表,其實(shí)也是笛卡兒積,與CROSS JOIN等價(jià),以下查詢同上述結(jié)果一樣。
這個(gè)可能很常見,但是大家一定要注意了,這樣就查詢了兩張表中所有組合的全集。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students,Majors
查詢結(jié)果:
| ID | Name | MajorName |
|---|---|---|
| 1 | Jack | English |
| 2 | Lucy | English |
| 1 | Jack | Computer |
| 2 | Lucy | Computer |
6)增加查詢條件
注意:在使用CROSS JOIN關(guān)鍵字交叉連接表時(shí),因?yàn)樯傻氖莾蓚€(gè)表的笛卡爾積,因而不能使用ON關(guān)鍵字,只能在WHERE子句中定義搜索條件。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students CROSS JOIN Majors
WHERE Students.MajorID = Majors.ID
查詢結(jié)果:
| ID | Name | MajorName |
|---|---|---|
| 1 | Jack | English |
查詢結(jié)果與INNER JOIN一樣,但是其效率就慢很多了。