[SQL] 查詢語法基本介紹 Part 4 (關連線處理/合併查詢_Join)

基本概念:

將儲存在多個資料表的欄位值取出,並使用合併查詢合併成所需要的查詢結果(一張大資料表)。
通常是使用資料表之間的關聯欄位來進行查詢,但也可以不使用關聯性建立資料查詢。


*將因正規化分散的資料合併成一張表(JOIN)*

Select (要找什麼樣的資料欄位)
From (從哪些資料表)
Where (各表之間怎麼連/各表之間的關聯性)

備註:基本上JOIN的操作都會需要使用ER圖!

類型介紹:

1. INNER JOIN 內部合併查詢

查詢在兩張資料表中,彼此都存在且符合合併查詢條件的資料。
若各自只出現在自己的資料表中的資料則全部不要。

換個說法就是,兩邊資料表都有資料時才會合併,對方沒有的就刪掉(左右不相等的就刪掉/其中一邊有NULL值的也會刪掉。)


範例:

列出身分證號、姓名、地址、電話

SELECT
userinfo.uid, cname, address, tel

FROM userinfo, live, house, phone
WHERE
userinfo.uid = live.uid AND
live.hid = house.hid AND
house.hid = phone.hid

2. LEFT (OUTER) JOIN 左側外部合併查詢

在合併的兩個資料表中,取回左邊資料表內的所有紀錄資料,不管右邊資料是否有相對應的資料存在。

換一種說法:

左側外部合併查詢中,關聯線的左側資料比較多。
除了兩邊共有的資料外,也取出左側的資料表的其他紀錄。

重點提醒:

若有合併欄位無資料,資料庫會給該欄位NULL值。
如果要讓NULL值顯示自訂的訊息。可用isnull(欄位, “自訂的訊息”)。



備註:
如果資料型態不同,需轉換可使用 cast(欄位 as 資料型態)

用參考索引控制多的資料在同一邊(參考索引所在的那一邊)
資料多的在左邊->left join
反之 right join
left + right = outer join


範例:

列出身分證號、姓名、地址、電話

SELECT
userinfo.uid,
cname,
address,
tel

FROM
userinfo LEFT JOIN live
ON userinfo.uid = live.uid
LEFT JOIN house
ON live.hid = house.hid
LEFT JOIN phone
ON house.hid = phone.hid


查詢空屋數

// 這個會跑表出來

Select house.hid, house.address, uid /*選定要顯示結果的範圍欄位*/
From /*選定資料表範圍/交代資料表間如何結合?*/
House left join live on
House.hid = live.hid
Where uid is null /*給定條件*/


//算空屋數,就是UID為NULL的數量,利用count function。

Select count(*)
From
House left join live on /*也可以改用 right join,只是兩者要對調,因為資料大小*/
House.hid = live.hid
Where uid is null

3. RIGHT (OUTER) JOIN 右側外部合併查詢

右側外部合併查詢可以取回右邊資料表內的所有紀錄,而不論是否在左邊資料表裏有存在合併欄位值。

換一種說法:關連線右側的資料比較多。

基本上跟左側外部合併查詢一樣,只是反過來資料量多的在右側。

4. CROSS JOIN 交叉合併查詢

是關聯式代數的卡笛生乘積運算,其查詢結果的記錄數是兩個資料表記錄數的乘積。
未設定關聯而形成交叉對應。


--cross join (沒有設Join條件,強制合併)
select * from userinfo, live



重點提醒:

基本上如果查詢使用Cross Join,指令幾乎是錯的。

要注意JOIN時資料間的關係/關連是否正確,避免Cross Join發生!

若資料庫龐大,cross join 會使資料庫全速運轉JOIN,直到資料庫完成指令。若要停止該查詢指令,只能把資料庫完全關閉。

5. FULL OUTER JOIN完全外部合併查詢 [同場加映]

取回左、右邊資料表內的所有資料。

進階練習:請列出每個人有多少支電話。(人>房子>電話)

解法一

select userinfo.uid,count(tel)
from
userinfo left join live on
userinfo.uid = live.uid
left join phone on
live.hid = phone.hid
group by userinfo.uid

解法二

select uid, sum(n) from
(
select userinfo.uid, iif(tel is null,0,1) as n
from
userinfo left join live on
userinfo.uid = live.uid
left join phone on
live.hid = phone.hid
) as a
group by uid

補充:iif() function 邏輯函式

IIF ( boolean_expression, true_value, false_value )

根據布林運算式判斷欄位值,並回傳true/false的指定值。


文章內容除取自上課筆記外,亦有參考書籍 SQL Server 2017/2016 資料庫設計與開發實務

留言

Popular Posts

[T-SQL] T-SQL 基本介紹_筆記

[SQL] 查詢語法基本介紹 Part 5 (視觀表 View)

[SQL] MS-SQL資料庫卸離與備份還原