1. 程式人生 > >淺談數據庫聯合查詢

淺談數據庫聯合查詢

com 右連接 tab 其中 過時 padding right 分析 union all

http://www.cnblogs.com/Candies/p/4142576.html

本文介紹以下內容:

LFET JOIN、RIGHT JOIN、INNER JOIN、UNION、UNION ALL、FULL JOIN等!

測試數據(以下數據未經考證,非真實有效數據,僅作為本次學習的測試數據!)

全國大學排名TOP20
No. 校名 地區
1 北京大學 北京 周其
2 大學 北京 秉林 理工
3 浙江大學 浙江 楊衛
4 復旦大學 上海 玉良
5 南京大學
6 上海交通大學 上海
7 大學
湖北 曉紅
8 中國人民大學 北京 寶成
9 中科技大學 湖北 李培根 理工
10 中山大學 寧生
11 吉林大學 吉林 展濤
12 四川大學 四川 和平
13 北京範大學 北京 秉林
14 南開大學 天津
15 中南大學 湖南 黃伯雲
16 大學
17 爾濱大學 理工
18 中國科技大學 安徽 侯建國 理工
19 西安交通大學 西 南寧
20 大學 福建 朱崇

數據庫表結構和數據SQL(使用Navicat從MYSQL導出):

技術分享 View Code

利用以下SQL可以查詢出以上的表格並了解表之間的關系:

技術分享
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
技術分享

修改部分測試數據:

SCHOOL:
BF8085E385004A5295F950F390C67476 四川大學 四川 1 12
5C354FDA736C4D189C97BEE8DDD0D0E6 山東大學 山東 1 16
-->
BF8085E385004A5295F950F390C67475 四川大學 四川 1 12
5C354FDA736C4D189C97BEE8DDD0D0E7 山東大學 山東 1 16

SCHOOLMASTER:
5496350FC7F0455A96268FC76AE11A01 陳俊 8150DCFA7F6144D6A77A109977538047
-->
5496350FC7F0455A96268FC76AE11A01 陳俊 8150DCFA7F6144D6A77A109977538046

繼續使用以上SQL查詢出高校排名:

查詢結果如下表:

01 北京大學 北京 周其
02 大學 北京 秉林 理工
03 浙江大學 浙江 楊衛
04 復旦大學 上海 玉良
05 上海交通大學 上海
06 大學 湖北 曉紅
07 中國人民大學 北京 寶成
08 中科技大學 湖北 李培根 理工
09 中山大學 寧生
10 吉林大學 吉林 展濤
11 北京範大學 北京 秉林
12 南開大學 天津
13 中南大學 湖南 黃伯雲
14 爾濱大學 理工
15 中國科技大學 安徽 侯建國 理工
16 西安交通大學 西 南寧
17 大學 福建 朱崇

數據庫中查詢分為:內連接、外連接、全連接,其中外連接分為左外連接(左連接)、右外連接(右連接)。

以下練習只關註表SCHOOL和表SCHOOLMASTER之間的連接關系,不關註表SCHOOL和表SCHOOLTYPE之間的連接關系,所以表SCHOOL和表SCHOOLTYPE之間使用LEFT JOIN進行聯合查詢。

左外連接(左連接):

使用以上測試數據,查詢所有大學的校名和校長:
SQL:

技術分享
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
LEFT JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
技術分享

查詢結果:

01 北京大學 北京 周其
02 大學 北京 秉林 理工
03 浙江大學 浙江 楊衛
04 復旦大學 上海 玉良
05 南京大學
06 上海交通大學 上海
07 大學 湖北 曉紅
08 中國人民大學 北京 寶成
09 中科技大學 湖北 李培根 理工
10 中山大學 寧生
11 吉林大學 吉林 展濤
12 四川大學 四川
13 北京範大學 北京 秉林
14 南開大學 天津
15 中南大學 湖南 黃伯雲
16 大學
17 爾濱大學 理工
18 中國科技大學 安徽 侯建國 理工
19 西安交通大學 西 南寧
20 大學 福建 朱崇


左連接查詢:以左表(LEFT JOIN左邊的表:表SCHOOL)為主表,即使右表(LEFT JOIN右邊的表:表SCHOOLMASTER)沒有匹配的數據,也從左表返回所有行數據。

以上SQL還可以寫成

技術分享
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
LEFT OUTER JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT OUTER JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
技術分享

這也是左外連接簡稱為左連接的原因。

或者

技術分享
SELECT
    SCHOOL.SORTKEY,
    SCHOOL.SCHOOLNAME,
    SCHOOL.SCHOOLLOCATION,
    SCHOOLMASTER.NAME,
    SCHOOLTYPE.TYPENAME
FROM
    SCHOOL,
    SCHOOLMASTER,
    SCHOOLTYPE
WHERE
    SCHOOL.SCHOOLID = SCHOOLMASTER.SCHOOLID(+)
AND SCHOOL.SCHOOLTYPE = SCHOOLTYPE.TYPEID(+)
ORDER BY
    SCHOOL.SORTKEY
技術分享

以上SQL也是用了左連接,因為(+)在右側,所以“(+)”所在位置的另一側為連接的方向,不過這種方式已經過時了。

右外連接(右連接):

使用以上測試數據,查詢所有校長管理的學校:
SQL:

技術分享
SELECT
    M.NAME,
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,    
    T.TYPENAME
FROM
    SCHOOL S
RIGHT JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
技術分享

查詢結果:

周其 01 北京大學 北京 綜合
秉林 02 大學 北京 理工
楊衛 03 浙江大學 浙江 綜合
玉良 04 復旦大學 上海 綜合
06 上海交通大學 上海 綜合
曉紅 07 大學 湖北 綜合
寶成 08 中國人民大學 北京 綜合
李培根 09 中科技大學 湖北 理工
寧生 10 中山大學
展濤 11 吉林大學 吉林 綜合
秉林 13 北京範大學 北京 師範
14 南開大學 天津 綜合
黃伯雲 15 中南大學 湖南 綜合
17 爾濱大學 黑龍江 理工
侯建國 18 中國科技大學 安徽 理工
南寧 19 西安交通大學 西 綜合
朱崇 20 大學 福建
和平

右連接查詢:以右表(RIGHT JOIN右邊的表:表SCHOOLMASTER)為主表,即使左表(RIGHT JOIN左邊的表:表SCHOOL)沒有匹配的數據,也從右表返回所有行數據。

以上SQL還可以寫成

技術分享
SELECT
    M.NAME,
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,    
    T.TYPENAME
FROM
    SCHOOL S
RIGHT OUTER JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
技術分享

這也是右外連接簡稱為右連接的原因。

或者

技術分享
SELECT
        SCHOOLMASTER.NAME,
    SCHOOL.SORTKEY,
    SCHOOL.SCHOOLNAME,
    SCHOOL.SCHOOLLOCATION,    
    SCHOOLTYPE.TYPENAME
FROM
    SCHOOL,
    SCHOOLMASTER,
    SCHOOLTYPE
WHERE
    SCHOOL.SCHOOLID(+) = SCHOOLMASTER.SCHOOLID
AND SCHOOL.SCHOOLTYPE = SCHOOLTYPE.TYPEID(+)
ORDER BY
    SCHOOL.SORTKEY
技術分享

以上SQL也是用了右連接,因為(+)在左側,所以“(+)”所在位置的另一側為連接的方向。

學習完左連接和右連接後,比較一下以下的SQL:

技術分享
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME
FROM
    SCHOOL S
LEFT JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
ORDER BY
    S.SORTKEY
技術分享 技術分享
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME
FROM
    SCHOOLMASTER M
RIGHT JOIN SCHOOL S ON S.SCHOOLID = M.SCHOOLID
ORDER BY
    S.SORTKEY
技術分享

運行以上兩句SQL後,發現查詢結果是一致的。雖然第一句SQL使用的是LEFT JOIN,而第二句使用的是RIGHT JOIN。

根據上文中左連接查詢、右連接查詢的定義:

左連接查詢:以左表為主表,即使右表沒有匹配的數據,也從左表返回所有行數據。
右連接查詢:以右表為主表,即使左表沒有匹配的數據,也從右表返回所有行數據。

分析以上兩句SQL。

第一句(LEFT JOIN):因為使用了左連接查詢,所以以左表SCHOOL為主表,返回查詢結果;

第二句(RITHT JOIN):因為使用了右連接查詢,所以以右表SCHOOL為主表,返回查詢結果。

所以主表為同一數據表,查詢結果相同。

也就是說在軟件開發過程中,針對某一功能需求,使用左連接查詢或者右連接查詢以及其他查詢都是可以的,只要查詢結果正確即可。

同時,也可以用多種查詢方式檢查SQL的正確性。

左連接查詢、右連接查詢等各種查詢方式並沒有錯誤,只要符合功能需求即可。這一觀點在後文以及以後的工作中也會得到證實。

內連接查詢:

使用以上測試數據,查詢所有學校和校長,特別指出的是,沒有校長的學校、沒有領導學校的校長不要顯示:

SQL:

技術分享
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
技術分享

查詢結果:

01 北京大學 北京 周其 綜合
02 大學 北京 顧秉林 理工
03 浙江大學 浙江 楊衛 綜合
04 復旦大學 上海 楊玉良 綜合
06 上海交通大學 上海 綜合
07 大學 湖北 李曉紅 綜合
08 中國人民大學 北京 寶成 綜合
09 中科技大學 湖北 李培根 理工
10 中山大學 寧生 綜合
11 吉林大學 吉林 展濤 綜合
13 北京範大學 北京 秉林 師範
14 南開大學 天津 綜合
15 中南大學 湖南 黃伯雲 綜合
17 爾濱大學 王樹國 理工
18 中國科技大學 安徽 侯建國 理工
19 西安交通大學 西 鄭南寧 綜合
20 大學 福建 朱崇 綜合

內連接查詢:如果表中有至少一個匹配,則返回行數據。

以上SQL還可以寫成

技術分享
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
INNER JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
INNER JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
技術分享

也就是說INNER JOIN 等同於 JOIN,為了方便起見,一般直接使用JOIN。

UNION、UNION ALL:

UNION 操作符用於合並兩個或多個 SELECT 語句的結果集。
請註意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型。同時,每條 SELECT 語句中的列的順序必須相同。

SQL:

技術分享
(
    SELECT
        S.SCHOOLID ID,
        S.SCHOOLNAME NAME
    FROM
        SCHOOL S
)
UNION
(
    SELECT
        M . ID ID,
        M . NAME NAME
    FROM
        SCHOOLMASTER M
)
UNION
(
    SELECT
        TYPEID ID,
        TYPENAME NAME
    FROM
        SCHOOLTYPE
)
技術分享

查詢結果:

0BAEEEBEE1A444EAA33FF61652F80F73 吉林大學
0C0D5616B55E42139242625E58C2D389 中國科技大學
1
12276D26BC4F4197B42D950681F924AB 浙江大學
2 理工
292812F98C394CB5846CFA1448094A24 爾濱大學
2B849F065600462C8D45BC2E781301F2 中科技大學
2BE4929EBA0D4AB983B2279D3C12711D 李培根
3 師範
339616FE14BE4D3282C3AA1BCDD18155 寶成
4 其他
40280309A8784F68ACB786E5B5DE556A 復旦大學
415F43C2F25C4A26BDEADBA1668E8177 寧生
44E4F771356C465DB02AD54A01C2ABDE 上海交通大學
49FBE5183F5A43E4B975B654A3399F61
4A3763D5528B49C299489C151620CD19 大學
4D5FD475D8204070B49944A01DB6F768 展濤
5496350FC7F0455A96268FC76AE11A01
54D90CFD0F104EFCB299D5098BF99386 中山大學
5C354FDA736C4D189C97BEE8DDD0D0E6 大學
5C5E20AEE6B44F9E8042010FB833E2E4 秉林
5FD7213082F14FA9A34B59CA614F6CFA 楊衛
8150DCFA7F6144D6A77A109977538047 南京大學
89381DEB8AFA482B9769DF8F024F04B2
8A17B2CC81B64DF78CCE0D75E21BF77B 中南大學
921BA4BC616244C68AE017BE623EE33A 南寧
977A97CC47C4482BA9A9359AAC4CEF66 大學
9E57F240DF0B4F57BBC20D0FE1CA118C 黃伯雲
ACC1B581908D49538DF97E06D15B9EEB 玉良
B45EA8CDE6554555921B7D293BAC36F2 北京範大學
B4E99F17053B4DD9BFF4EA27D3DB9F6B 周其
BF8085E385004A5295F950F390C67476 四川大學
C15BD0AB3EF4468A96557A870293BA88 北京大學
C50259B9240F4C88B38B954575079343 西安交通大學
CA9525B7E1AA41C984E26DEA95381FD9 曉紅
CC463BB9D6CB4D2DA8B1687A1138E73E
D1993E4EEB9A4017BA2D46E0EA16D1C6
D27B3A5FB8AA489A987D14288871CC6E 中國人民大學
D49DF755223C442EA99449193D98A465 和平
D49EC73FA4D3470B8F355812B0BD4CA3 朱崇
D4D879DAF2E14E6DA129EC8E46F1E5D4 南開大學
DD0C1777563B49E7B4E98FCBC3A77E0D 侯建國
FA4CE2FB3B264F0A8BFB55B638D46BC1 秉林
FCBB60720A9749B1AE72CBE5BE388E22 大學

以上SQL僅僅為了說明UNION的功能,沒有具體意義。

當列數據有重復時,UNION只能查詢出一條記錄,這時候就需要使用UNION ALL進行查詢。

全連接查詢:

SQL:

技術分享
SELECT
    S.SORTKEY,
    S.SCHOOLNAME,
    S.SCHOOLLOCATION,
    M.NAME,
    T.TYPENAME
FROM
    SCHOOL S
FULL JOIN SCHOOLMASTER M ON S.SCHOOLID = M.SCHOOLID
LEFT JOIN SCHOOLTYPE T ON S.SCHOOLTYPE = T.TYPEID
ORDER BY
    S.SORTKEY
技術分享

查詢結果:

01 北京大學 北京 周其 綜合
02 大學 北京 顧秉林 理工
03 浙江大學 浙江 楊衛 綜合
04 復旦大學 上海 楊玉良 綜合
05 南京大學 綜合
06 上海交通大學 上海 張傑 綜合
07 武漢大學 湖北 李曉紅 綜合
08 中國人民大學 北京 紀寶成 綜合
09 華中科技大學 湖北 李培根 理工
10 中山大學 許寧生 綜合
11 吉林大學 吉林 展濤 綜合
12 四川大學 四川 綜合
13 北京師範大學 北京 鐘秉林 師範
14 南開大學 天津 龔克 綜合
15 中南大學 湖南 黃伯雲 綜合
16 大學 山東 綜合
17 爾濱大學 理工
18 中國科技大學 安徽 侯建國 理工
19 西安交通大學 陜西 鄭南寧 綜合
20 大學 福建 朱崇 綜合
和平

全連接查詢:只要其中某個表存在匹配,就返回行數據。

淺談數據庫聯合查詢