【概念區分】笛卡爾積,自然連接,內連接,外連接(左,右,全)


本文章嘗試解決一下問題

1.笛卡爾積存在的意義是什么?

2.”cross join 笛卡爾積“和”full join 全連接“和"inner join內連接"的區別在哪里?

3. 既然”連接條件“可以寫在where字句里面,為什么還要用on關鍵字?

4.自然連接和內連接有什么關系嗎?

 

 

1.笛卡爾積存在的意義是什么?

雖然”笛卡爾積“在實際問題中很少會用到,但”笛卡爾積“不僅僅存在數學意義,也存在現實意義的,比如集合A是一個班的學生,集合B是所有的選修課,A與B的笛卡爾積,表示了學生選擇課程的所有可能性

mysql> select * from A;
+--------------+
| student_name |
+--------------+
| 張學友       |
| 劉德華       |
+--------------+
2 rows in set (0.00 sec)
mysql> select * from B;
+--------------+
| subject_name |
+--------------+
| 語文         |
| 數學         |
| 法律         |
+--------------+
3 rows in set (0.00 sec)

那么”學生選課“就擁有6種可能性,數學中的”排列組合“通過2*3=6得出來,MySQL用”corss join“來計算笛卡爾積

mysql> select * from A cross join B order by student_name;
+--------------+--------------+
| student_name | subject_name |
+--------------+--------------+
| 劉德華       | 數學         |
| 劉德華       | 法律         |
| 劉德華       | 語文         |
| 張學友       | 法律         |
| 張學友       | 語文         |
| 張學友       | 數學         |
+--------------+--------------+
6 rows in set (0.00 sec)

有同樣效果的是

select * from A , B

 

2.”cross join 笛卡爾積“和”full join 全連接“和"inner join內連接"的區別在哪里?

cross join 象征着返回所有的情況,默認不使用 where進行過濾的,因為篩選之后就失去了”所有可能性“這種意義了,而 inner join默認使用on進行”匹配“,如果不使用on返回的是 cross join的所有可能性,也就失去了意義了

 

集合a(1,2,3),集合b(1,2,3)

1.笛卡爾積——返回3 * 3 =9 條記錄,默認不用where

2.內連接——返回3條記錄,默認使用on

 

3. 既然”連接條件“可以寫在where字句里面,為什么還要用on關鍵字?

這是因為有兩個原因

a. 更加清晰的把表與表之間”做連接”的條件,與其他條件區分開來,這好比小工的人力資源和行政是一體的,但公司大了,兩者就可以分開,分工更清晰

b. 在 ”inner join 內連接“ 中,on和where雖然意義不同,但結果相同,但在 outer join 中,結果就不一樣了,匹配條件放在where中是不會產生NULL值的

 

4.自然連接和內連接有什么關系嗎?

“自然連接”和“內連接”的區別,在於對“重合的相同的部分”處理方式不同

1."natrual join 自然連接"的處理方式:既然重復了,就丟掉一份,好比distinct

2.“inner join 內連接”的處理方式:雖然重復,但兩份都保留

假設有A,B兩個集合,其中有兩個字段是重復的

自然連接是“去重”,有點像distinct

mysql> select * from A natural join B;
+------+------+-----------+-----------+
| b    | c    | a         | d         |
+------+------+-----------+-----------+
| 1111 | 2222 | 劉德華    | 投名狀    |
| 3333 | 4444 | 梁朝偉    | 花樣年    |
+------+------+-----------+-----------+
2 rows in set (0.00 sec)

“內連接”的方式,是把所有重復的都保留(當然額外用where條件篩選是另外一回事了)

mysql> select * from A inner join B on A.b=B.b;
+-----------+------+------+------+------+-----------+
| a         | b    | c    | b    | c    | d         |
+-----------+------+------+------+------+-----------+
| 劉德華    | 1111 | 2222 | 1111 | 2222 | 投名狀    |
| 梁朝偉    | 3333 | 4444 | 3333 | 4444 | 花樣年    |
+-----------+------+------+------+------+-----------+
2 rows in set (0.00 sec)

 

最后附上一張關於連接的圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM