SQL查詢數據的時候,經常需要通過Join連接,把幾個表的數據組合在一起查詢,有點類似Excel的Vlookup,但又有多種不同的形態,下面以一個常見的業務場景為例,簡單介紹一下區別:
某班級開展了期中考試,成績出來之后,為了保護學渣的隱私,老師在群里面發布的成績表沒有學生姓名,只有學號、課程、成績:
成績表(A) | ||
ID | Course | Mark |
學號 | 課程 | 成績 |
1 | 語文 | 99 |
1 | 數學 | 100 |
2 | 語文 | 60 |
3 | 語文 | 70 |
至於具體學生姓名,老師自己另外有一個學生姓名表進行登記,不過由於老師工作比較馬虎,這個姓名表登記不太完整:
學生表(B) | |
ID | Name |
學號 | 姓名 |
1 | 小曾 |
2 | 小陳 |
4 | 小黃 |
現在如果老師想做一個完整的成績表,包含了學號、課程、成績及姓名的,類似如下格式,就需要用到Join語句了:
完整成績表(C) | |||
ID | Course | Mark | Name |
學號 | 課程 | 成績 | 姓名 |
場景一:老師只想知道成績表里面這些人究竟是誰,至於沒來參加考試的,即便在姓名表里面,老師也不需要知道。
這個時候就需要使用Left Join了:以左表為准,匹配右表,右有就返回,沒有就為空。
Select A.ID,A.Course,A,Mark,B.Name from A left join B on a.ID=B.ID
結果如下:
完整成績表(C) | |||
ID | Course | Mark | Name |
學號 | 課程 | 成績 | 姓名 |
1 | 語文 | 99 | 小曾 |
1 | 數學 | 100 | 小曾 |
2 | 語文 | 60 | 小陳 |
3 | 語文 | 70 | Null |
說明:
雖然3號同學語文考了70分,但是學生表中沒有他,作為無名之輩,他的姓名體現為Null。
雖然4號同學在學生表中,但是他沒來參加考試,所以結果直接沒有他。
場景二:老師只想知道學生表里面這些人的考試成績,至於不在學生表中的人,即便考了100分老師也不關心。
這個時候就需要使用Right Join了:以右表為准,匹配左表,左表有就返回,沒有就為空。
Select A.ID,A.Course,A,Mark,B.Name from A Right Join B on a.ID=B.ID
結果如下:
完整成績表(C) | |||
ID | Course | Mark | Name |
學號 | 課程 | 成績 | 姓名 |
1 | 語文 | 99 | 小曾 |
1 | 數學 | 100 | 小曾 |
2 | 語文 | 60 | 小陳 |
4 | Null | Null | 小黃 |
說明:
小黃同學在學生表中,但是沒參加考試,所以課程及成績為Null。
雖然3號同學語文考了70分,但是學生表中沒有他,所以結果直接沒有他。
場景三:老師只想知道在學生表里面、並且參加了考試的人的成績,其他情況不需要體現。
這個時候就需要用到Inner Join了:兩表匹配,只有兩個表中都有的數據才返回。
Select A.ID,A.Course,A,Mark,B.Name from A inner join B on a.ID=B.ID
結果如下:
完整成績表(C) | |||
ID | Course | Mark | Name |
學號 | 課程 | 成績 | 姓名 |
1 | 語文 | 99 | 小曾 |
1 | 數學 | 100 | 小曾 |
2 | 語文 | 60 | 小陳 |
說明:
小黃同學在學生表中,但是沒參加考試,所以結果直接沒有他。
雖然3號同學語文考了70分,但是學生表中沒有他,所以結果直接沒有他。
場景四:老師什么都想知道,要一個最完整的表,沒來考試或者來考試但沒有姓名的都要列出來。
這個時候就需要用到Full Outer Join了:兩表匹配,只要任意一個表有的數據就都返回。
Select A.ID,A.Course,A,Mark,B.Name from A full outer join B on a.ID=B.ID
結果如下:
完整成績表(C) | |||
ID | Course | Mark | Name |
學號 | 課程 | 成績 | 姓名 |
1 | 語文 | 99 | 小曾 |
1 | 數學 | 100 | 小曾 |
2 | 語文 | 60 | 小陳 |
3 | 語文 | 70 | Null |
4 | Null | Null | 小黃 |
說明:
3號同學是無名之輩,所以姓名是Null。
小黃同學沒參加考試,所以課程及成績都是Null。