今天,重刷了刷leetcode數據庫的題目,對數據庫連接查詢做一個記錄。
數據庫(join) 內連接、外連接、笛卡爾積
內連接(自身連接)
內連接有隱式內連接和顯示內連接兩種:
-
隱式(無join),from后跟多個表名,生成的中間臨時表是全部笛卡爾積。最后用where條件篩選
-
例如:
select A.Name from Employee as A, Employee as B where A.ManagerId=B.Id and A.Salary>B.Salary
-
-
顯示(有join),中間臨時表是經過ON子句過濾后的笛卡爾積。最后用where條件篩選
-
例如:a [INNER] JOIN b ON a.id=b.id
-
select A.name as Employee from Employee As A inner join Employee as B on A.ManagerId=B.Id where A.Salary>B.Salary
-
差異:隱式生成的是全部笛卡爾積,連接時生成的中間臨時表更大。on條件是生成中間臨時表的過濾條件;where條件是在臨時表生成好后,再對臨時表進行過濾的條件。
外連接
外連接有左連接、右連接、全連接三種:
-
左連接 a LEFT JOIN b ON a.id=b.id
-
左邊為主表,保留所有行(即使在右表沒有匹配的行),右表輸出滿足 on 條件的行,不滿足的輸出null
select A.FirstName, A.LastName, B.City, B.State from Person as A left join Address as B on A.PersonId=B.PersonId
-
-
右連接 a RIGHT JOIN b ON a.id=b.id
-
右邊為主表,保留所有行(即使在左表沒有匹配的行),左表輸出滿足 on 條件的行,不滿足的輸出null
select A.FirstName, A.LastName, B.City, B.State from Person as A right join Address as B on A.PersonId=B.PersonId
-
-
全連接 a FULL JOIN b ON a.id=b.id
- MySQL不支持全連接。一定要使用的話可以用左連接+右連接+去重=全連接。
笛卡爾積(交叉連接)
定義:是指在數學中,兩個集合 X 和 Y 的乘積 X * Y。
它不帶WHERE子句,返回被連接的兩個表所有數據行的乘積。a CROSS JOIN b , cross join可以省略。
select * from Person as A cross join Address as B
select * from Person as A, Address as B
例如,兩個表如圖:
A表的每一行會和B表的每一行組合,笛卡爾積是:
總結
子查詢執行時系統要先把子查詢轉化成連接查詢來實現,因此連接查詢執行時效率更高。
子查詢是把問題細分成子問題,然后解決,更符合人們的解決問題習慣。但是因為效率的原因,遇到一個問題盡量用連接查詢實現,如果連接查詢實現時很復雜或者實現不了,則可以考慮使用子查詢實現。