SQL多表查詢總結(jié)

前言

連接查詢包括合并、內(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一樣,但是其效率就慢很多了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • SQL語言基礎(chǔ) 本章,我們將會(huì)重點(diǎn)探討SQL語言基礎(chǔ),學(xué)習(xí)用SQL進(jìn)行數(shù)據(jù)庫的基本數(shù)據(jù)查詢操作。另外請注意本章的S...
    厲鉚兄閱讀 5,461評(píng)論 2 46
  • MySQL技術(shù)內(nèi)幕:SQL編程 姜承堯 第1章 SQL編程 >> B是由MySQL創(chuàng)始人之一Monty分支的一個(gè)版...
    沉默劍士閱讀 2,639評(píng)論 0 3
  • 昨晚睡晚了,今早竟然6點(diǎn)不到被噩夢驚醒,驚醒的瞬間想到的居然是,這是有人設(shè)計(jì)的夢境來盜夢的?然后繼續(xù)被這個(gè)念頭驚醒...
    阿雪_Michelle閱讀 168評(píng)論 0 2
  • 最近很多文章都在說婚姻不要將就,遇到真心相愛的再結(jié)婚,可要是一直遇不到怎么辦?” 這個(gè)問題引發(fā)了一個(gè)又一個(gè)的讀者接...
    思穎splendid閱讀 919評(píng)論 0 0
  • 今日小結(jié): 周一滬指呈現(xiàn)寬幅震蕩的格局,在經(jīng)歷了前期的11連陽后,今日上攻乏力,沖高回落,但滬指維持在3400點(diǎn)上...
    老張說財(cái)經(jīng)閱讀 268評(píng)論 0 0

友情鏈接更多精彩內(nèi)容