淺談數據庫聯合查詢
http://www.cnblogs.com/Candies/p/4142576.html
本文介紹以下內容:
LFET JOIN、RIGHT JOIN、INNER JOIN、UNION、UNION ALL、FULL JOIN等!
測試數據(以下數據未經考證,非真實有效數據,僅作為本次學習的測試數據!)
|
數據庫表結構和數據SQL(使用Navicat從MYSQL導出):
利用以下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查詢出高校排名:
查詢結果如下表:
|
數據庫中查詢分為:內連接、外連接、全連接,其中外連接分為左外連接(左連接)、右外連接(右連接)。
以下練習只關註表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
查詢結果:
|
左連接查詢:以左表(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
查詢結果:
|
右連接查詢:以右表(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
查詢結果:
|
內連接查詢:如果表中有至少一個匹配,則返回行數據。
以上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 )
查詢結果:
|
以上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
查詢結果:
|
全連接查詢:只要其中某個表存在匹配,就返回行數據。
淺談數據庫聯合查詢