【SQL】JOIN 連接:內連接、外連接、交叉連接、自連接、等值連接、自然連接


基本概念

關系模型(表)

關系模型由關系數據結構、關系操作集合和關系完整性約束三部分組成。

關系模型的數據結構非常簡單:一張扁平的二維表

  • 元組:二維表中的具有相同數據類型的某一行
  • 屬性:二維表中的具有相同數據類型的某一列
  • 笛卡爾積(Cartesian product):又稱直積,分別用集合A和集合B的一個元素作第一、第二元素構成有序對,所有這樣的有序對的集合稱為A和B的笛卡爾積,記作\(A×B\)
    其符號化表示為:\(A×B = {<x, y> | x∈A∧y∈B}\)
    易證:\(|A| = m\)\(|B| = n\),則\(|AB| = m*n\)。(\(|A|\)表示集合A的模,即 集合A中元素的個數為m個)

    例如:
    \(A={a, b}\), \(B={0, 1, 2}\),則
    \(A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}\)
    \(B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}\)


  • 表:是實實在在地保存數據的實體,寫入的數據都保存在表中
  • 視圖:是一個虛擬表,其內容由查詢定義
    同真實的表一樣,視圖包含一系列帶有名稱的列和行數據;但是,視圖並不在數據庫中以存儲的數據值集形式存在。
    行和列數據來自由定義視圖的查詢所引用的表,並且在引用視圖時動態生成。

  • 候選碼:若關系中的一個屬性或屬性組的值能夠唯一地標識一個元組,且他的真子集不能唯一的標識一個元組,則稱這個屬性或屬性組做候選碼。
  • 主鍵:如果在一個關系中,有多個候選碼可以選擇,則選定其中的一個作為該關系的主鍵。
    它的值用於唯一地標識表中的某一條記錄。主關鍵字是一種唯一關鍵字。

  • 碼:是一個或多個屬性的集合。
  • 超碼:是一個或多個屬性的集合,超碼中的這些屬性可以讓我們在一個實體集中唯一地標識一個實體。

    注意:雖然超碼可以唯一標識一個實體,但是可能大多數超碼中含有多余的屬性。所以我們需要候選碼。

  • 候選碼:是極小的超碼集,也就是它的任意真子集都不是超碼,而他本身是超碼。
  • 主碼:是被選中用來在一個關系中區分不同元組的候選碼。


我來舉個例子吧:
學生表(學號,身份證號,姓名,性別)

  • 超碼:(學號,性別)→(姓名)。學號和性別能唯一標識姓名一點問題都沒有,但是其實標識姓名,只用學號就能標識了,不需要性別。
  • 候選碼:(學號)→(姓名),(身份證號)→(姓名)。學號或身份證號都能唯一標識姓名。
  • 主碼:(學號)→(姓名)。這是人為選擇的,其實身份證號也能做主碼。

連接

多表查詢經常用到連接,各種連接之間的區別應該注意總結。

首先大概認識各種連接的關系和由來:
表之間的連接常有以下兩種:

  • 以JOIN關鍵字指定的連接,T-SQL擴展了以JOIN關鍵字指定連接的表示方式,使表的連接運算能力有所增強,以JOIN關鍵字指定的連接有三種類型:內連接、外連接、交叉連接(笛卡爾積)。

  • 在SELECT語句的WHERE子句中使用比較運算符給出連接條件,對表進行連接,將這種表示形式稱為連接謂詞表示形式。連接謂詞中的比較符可以是<<==>>=!=<>!<!>,當比較符為“=”時,就是等值連接,等值連接的結果中有重復列,在目標列中去除相同的字段名就是自然連接。

JOIN 連接

所謂"連接JOIN",就是兩張表根據關聯字段(就是ON后面的關聯條件),組合成一個數據集。
格式:表A JOIN 表B ON AB的關聯條件 JOIN 表C AC或AB的關聯條件

  • 內連接(inner join):(以左右表內匹配的記錄為主)表示只包含匹配的記錄。只返回兩張表匹配的記錄。
  • 外連接(outer join):表示還包含不匹配的記錄
    • 左連接(left join):(以左表所有的記錄為主)又稱左外連接,返回匹配的記錄,以及表A多余的記錄
    • 右連接(right join):(以右表所有的記錄為主)又稱右外連接,返回匹配的記錄,以及表B多余的記錄
    • 全連接(full join):(以兩個表所有的記錄為主)又稱全外連接,返回匹配的記錄,以及表A和表B各自的多余記錄
  • 交叉連接(cross join):即 做笛卡爾積運算。
    表A和表B不存在關聯字段,這時表A(共有n條記錄)與表B(共有m條記錄)連接后,一對一組合配對,會產生一張包含n*m條記錄的新表,返回新表。


上圖中,表A的記錄是123,表B的記錄是ABC,顏色表示匹配關系。返回結果中,如果另一張表沒有匹配的記錄,則用null填充。

注意:多表連接查詢會比直接使用自帶的API查詢表中的一個屬性,再根據屬性查詢另一個表,一個一個查詢來得快。所以,我們要善用多表連接查詢。

實例

學生表:

  • s_id:學生學號
  • s_name:學生名稱
  • s_class:學生班級

老師表:

  • t_id:老師id
  • t_class:老師管理的班級
  • t_name:老師名稱

內連接(INNER JOIN)

內連接:,JOININNER JOIN
如果輸入JOIN,那么默認就是INNER JOIN內連接

/* 內連接 */
SELECT * FROM student INNER JOIN teacher ON s_class=t_class

/* 我比較喜歡這種,但是上面那種效率會更高,因為 JOIN 的優先級高於 逗號,,所以如果可以的話,盡量使用上面的 */
SELECT * FROM student,teacher WHERE s_class=t_class

補充:
在使用 join 時,on 和 where 條件的區別如下:
1、on 條件是在生成臨時表時使用的條件,它不管 on 上的條件是否為真都會返回 left 或 right 表中的記錄,full 則具有 left 和 right 的特性的並集。
2、where 條件是在臨時表生成好后,再對臨時表進行過濾的條件。這時已經沒有 left join 的含義(必須返回左邊或者右邊表的記錄)了,條件不為真的就全部過濾掉。

而 inner jion 沒這個特殊性,則條件放在 on 中和 where 中,返回的結果集是相同的。

外連接(OUTER JOIN)

左外連接(LEFT JOIN)

左外連接:LEFT JOINLEFT OUTER JOIN

/* 左連接 */
SELECT * FROM student LEFT JOIN teacher ON s_class=t_class

右外連接(RIGHT JOIN)

右外連接:RIGHT JOINRIGHT OUTER JOIN

/* 右連接 */
SELECT * FROM student RIGHT JOIN teacher ON s_class=t_class

全外連接(FULL JOIN)

全外連接:FULL JOINFULL OUTER JOIN

注意:Oracle數據庫支持full join,mysql是不支持full join的,但仍然可以同過左外連接+union+右外連接實現。

/* 全連接(不適用於MYSQL) */
SELECT * FROM student FULL JOIN teacher ON s_class=t_class

/* 全連接 */
SELECT * FROM student LEFT JOIN teacher ON s_class=t_class
UNION
SELECT * FROM student RIGHT JOIN teacher ON s_class=t_class

交叉連接(笛卡爾積)(CROSS JOIN)

笛卡爾積:對所有元素一一映射,排列組合

/* 交叉連接 */
SELECT * FROM student CROSS JOIN teacher 

其他連接

自連接

自連接作為一種特例,可以將一個表與它自身進行連接,稱為自連接。若要在一個表中查找具有相同列值的行,則可以使用自連接。使用自連接時需為表指定兩個別名,且對所有列的引用均要用別名限定。

SELECT a.學號, a.課程號, b.課程號, a.成績
 FROM student a  JOIN  student b 
   ON  a.成績=b.成績 AND  a.學號=b.學號 AND  a.課程號!=b.課程號

image

等值連接(相等連接)

SELECT student.* , teacher.*
 FROM  student , teacher
 WHERE student.class = teacher.class

使用“=”關系將表連接起來的查詢,其查詢結果中列出被連接表中的所有列,包括其中的重復列。

自然連接

數據庫應用中最常用的是“自然連接”,它在目標列中去重相同的字段名,只留下一個。

我們將student表和teacher表中的s_class和t_class字段統一命名為相同的字段名class,方便展示自然連接。

SELECT student.* , teacher.課程號, teacher.成績
FROM student , teacher
WHERE student.class = teacher.class
SELECT * FROM student NATURAL JOIN teacher

image
進行自然連接運算要求兩個表有共同屬性(列),自然連接運算的結果表是在參與操作的兩個表的共同屬性上進行等值連接后,再去除重復的屬性后所得的新表。

等值連接和自然連接的區別:
1)等值連接中不要求相等屬性值的屬性名相同,而自然連接要求相等屬性值的屬性名必須相同,即兩關系只有在同名屬性才能進行自然連接。

2)等值連接不將重復屬性去掉,而自然連接去掉重復屬性,也可以說,自然連接是去掉重復列的等值連接。


免責聲明!

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



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