關於SQL中Union和Join的用法
一直以來,對於資料庫SQL方面都是半吊子水平,能寫一些基本的增刪改查的語句,大部分時間都是用下Where,偶爾用用Order By、Limit,Like什麼的。連表查詢也是一些很簡單的使用。至於那些高階用法,都還給老師了。最近接騰訊的IDIP的SDK,需要查詢一些遊戲資料,發現自己的SQL水平不夠用,溫習了一些以前忘記的語法,順便記錄一下,方便以後偶爾來查查。
Union
UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。
請注意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的資料型別。同時,每條 SELECT 語句中的列的順序必須相同。
//聯合兩個表,沒有重複
SELECT E_Name FROM Employees_China
UNION
SELECT E_Name FROM Employees_USA
資料來源:
結果:
預設地,UNION 操作符選取不同的值。如果允許重複的值,請使用 UNION ALL。
另外,UNION 結果集中的列名總是等於 UNION 中第一個 SELECT 語句中的列名。
//聯合兩個表,允許重複
SELECT E_Name FROM Employees_China
UNION ALL
SELECT E_Name FROM Employees_USA
結果:
JOIN
有時為了得到完整的結果,我們需要從兩個或更多的表中獲取結果。我們就需要執行 join。
資料庫中的表可通過鍵將彼此聯絡起來。主鍵(Primary Key)是一個列,在這個列中的每一行的值都是唯一的。在表中,每個主鍵的值都是唯一的。這樣做的目的是在不重複每個表中的所有資料的情況下,把表間的資料交叉捆綁在一起。
資料來源:
Persion表:
Orders表:
//使用連表查詢
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons, Orders
WHERE Persons.Id_P = Orders.Id_P
//使用join 查詢
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders
ON Persons.Id_P = Orders.Id_P
ORDER BY Persons.LastName
結果:
不同的 SQL JOIN
除了我們在上面的例子中使用的 INNER JOIN(內連線),JOIN預設使用內連線,可以省略INNER。 我們還可以使用其他幾種連線。
下面列出了您可以使用的 JOIN 型別,以及它們之間的差異。
- JOIN: 如果表中有至少一個匹配,則返回行(INNER JOIN 與 JOIN)
- LEFT JOIN: 即使右表中沒有匹配,也從左表返回所有的行
- RIGHT JOIN: 即使左表中沒有匹配,也從右表返回所有的行
- FULL JOIN: 只要其中一個表中存在匹配,就返回行
LEFT JOIN
//使用left join查詢,只要左表有匹配的條件,就會生成一行,右表的列值為空。
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
LEFT JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName
結果:
RIGHT JOIN
//使用right join查詢,只要右表有匹配的條件,就會生成一行,左表的列值為空。
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
RIGHT JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName
結果:
FULL JOIN
//使用full join查詢,只要其中一個表中存在匹配,就會生成一行,另一個表的列值為空。
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
FULL JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName
結果:
多表連線
有時候會遇到需要多個表連線的情況,只要遵守以下規則就可以輕鬆的應對多表連線的情況了。
- 在可以指定一個表名的任何地方,都可以指定一個括號括起來的join子句。
- 在兩個表的一個完整join語句出現的任何一個地方,我們都可以只用一個表名來代替它。所謂“兩個表的一個完整join語句”也即“join子句”,就是指如“A join B on A.a= B.b”這樣一個完整的句子。
比如:欲連線ABCDE五個表
//A: 可以這樣:
Select * from A inner join(((
B inner join C on B.b = C.c)
inner join D on B.b = D.d)
inner join E on D.d = E.e)
on A.a = E.e
//B: 也可以這樣:
select * from (((
A inner join B on A.a = B.b)
inner join C on C.c = A.a)
inner join D on D.d = C.c)
inner join E
on E.e = D.d
//C: 也可以這樣:
select * from
A inner join B on A.a = B.b
inner join C on C.c = A.a
inner join D on D.d = C.c
inner join E on E.e = D.d
我們可以先把A和B連線起來,然後將結果與C連線,當然,如果C只和B相關而不和A相關的話,我們也可以先把B和C連線起來,結果再與A連線,只要保持關係是正確的,你可以以任意方式來定義巢狀的join。
先記錄到這裡吧,後面有時間再繼續溫習下。