上次博文引用了各鏈接的示意圖,未作詳述,本文補充對數據庫各鏈接的實例描述。sql
數據爲klass
與student
的關係,班級一對多學生,沒有加外鍵。數據庫
數據關係以下:1
班的Hello Kitty
和史努比,2
班的米老鼠和唐老鴨,3
班沒學生,葫蘆娃沒有班級。spa
關係型數據庫,即數據之間是有所關係的。3d
就如咱們當前場景下的klass
與student
表同樣,兩表中的數據在實際的業務場景中是有所關聯的,學生屬於哪一個班級,這種多對一的關係,咱們在學生表中加上klass_id
一列存儲這種關係。code
班級與學生的關係經過klass_id
進行維護。blog
簡單的單表查詢:get
SELECT * FROM `klass`;
若是想同時看教師和班級的數據,就須要進行多表查詢了:it
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass`, `student` WHERE `klass`.`id` = `student`.`klass_id`;
進行多表查詢時,實際上是將兩表的記錄先作笛卡爾積,再根據WHERE
條件對數據進行過濾。io
不加WHERE
條件的示例:class
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass`, `student`;
很慚愧,從我學數據庫到如今,每次我手寫這樣需求的SQL
,都是使用的這種方法進行多表查詢。
試想,若是咱們全部的多表查詢,都使用WHERE
進行過濾,這會形成一個很嚴重的問題。
若是查詢條件很複雜的話,會致使WHERE
語句不只充斥着數據表層面的鏈接條件,還充斥着各類業務條件,會讓WHERE
語句很不直觀。
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass`, `student` WHERE `klass`.`id` = `student`.`klass_id`;
參考問題:INNER JOIN ON vs WHERE clause - StackOverflow
這種場景下推薦使用內鏈接代替WHERE
。
內鏈接可更好地完成上述需求:
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass` INNER JOIN `student` ON `klass`.`id` = `student`.`klass_id`;
而且,鏈接的條件寫在ON
裏,WHERE
只寫業務條件,更直觀。
內鏈接:內鏈接基於鏈接謂詞將兩張表(如A
和B
)的列組合在一塊兒,產生新的結果表。查詢會將A
表的每一行和B
表的每一行進行比較,並找出知足鏈接謂詞的組合。當鏈接謂詞被知足,A
和B
中匹配的行會按列組合(並排組合)成結果集中的一行。
示例數據有三個班,可是3
班由於沒有任何學生與之關聯,因此不符合查詢謂語中的klass.id = student.klass_id
,因此沒有3
班的信息。
一樣地,由於學生「葫蘆娃」沒有班級,也不符合查詢條件,一樣沒有出如今內鏈接的查詢 結果中。
注:在錶鏈接中NULL != NULL
若是想讓數據顯示徹底,就須要左鏈接與右鏈接了。
klass
錶鏈接student
表,klass
算左表,student
算右表。
左鏈接,顯示左表全部數據:
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass` LEFT JOIN `student` ON `klass`.`id` = `student`.`klass_id`;
3
班在左鏈接中出現了:
右鏈接,顯示右表全部數據:
SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name` FROM `klass` RIGHT JOIN `student` ON `klass`.`id` = `student`.`klass_id`;
「葫蘆娃」在右鏈接中出現了:
寶劍鋒從磨礪出,梅花香自苦寒來。