原文位址(原文寫的挺全的,直接拿過來了)
由于 SQL Join 似乎被預設為基礎,同時利用 ‘文氏圖表’ 解釋它,乍一看似乎是很自然的選擇。然而,就像文章下面說的,我也發現在實際測試中,文氏圖并沒有完全符合SQL Join 文法。
通過圖文并茂的方式對SQL的Join進行簡單的介紹:join大緻分為以下七種情況:
1準備資料
- DROP TABLE [dbo].[test_a]
- GO
- CREATE TABLE [dbo].[test_a] (
- [id] int NULL ,
- [name] varchar(255) NULL
- )
- GO
- -- ----------------------------
- -- Records of test_a
- -- ----------------------------
- INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'1', N'蘋果')
- GO
- GO
- INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'2', N'橘子')
- GO
- GO
- INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'3', N'鳳梨')
- GO
- GO
- INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'4', N'香蕉')
- GO
- GO
- INSERT INTO [dbo].[test_a] ([id], [name]) VALUES (N'5', N'西瓜')
- GO
- GO
- -----------------------------------------------------------
- DROP TABLE [dbo].[test_b]
- GO
- CREATE TABLE [dbo].[test_b] (
- [id] int NULL ,
- [name] varchar(255) NULL
- )
- GO
- -- ----------------------------
- -- Records of test_b
- -- ----------------------------
- INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'1', N'梨子')
- GO
- GO
- INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'2', N'蘋果')
- GO
- GO
- INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'3', N'草莓')
- GO
- GO
- INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'4', N'桃子')
- GO
- GO
- INSERT INTO [dbo].[test_b] ([id], [name]) VALUES (N'5', N'香蕉')
- GO
- GO
2示例介紹
A.Inner join
産生A和B的交集。
- SELECT
- *
- FROM
- test_a
- INNER JOIN test_b ON test_a.name = test_b.name
B. Full outer join
産生A和B的并集。對于沒有比對的記錄,則以null做為值。
- SELECT
- *
- FROM
- test_a
- FULL OUTER JOIN test_b ON test_a.name = test_b.name
C.Left outer join
産生表A的完全集,而B表中比對的則有值,沒比對的以null值取代。
- SELECT
- *
- FROM
- test_a
- LEFT OUTER JOIN test_b ON test_a.name = test_b.name
D. Left outer join on where
産生在A表中有而在B表中沒有的集合。
- SELECT
- *
- FROM
- test_a
- LEFT OUTER JOIN test_b ON test_a.name = test_b.name
- WHERE
- test_b.name IS NULL
E. RIGHT OUTER JOIN
産生表B的完全集,而A表中比對的則有值,沒比對的以null值取代。
- SELECT
- *
- FROM
- test_a
- RIGHT OUTER JOIN test_b ON test_a.name = test_b.name
F. right outer join on where
産生在B表中有而在A表中沒有的集合。
- SELECT
- *
- FROM
- test_a
- RIGHT OUTER JOIN test_b ON test_a.name = test_b.name
- WHERE
- test_a.name IS NULL
G. FULL OUTER JOIN WHERE
産生(A表中有但B表沒有)和(B表中有但A表中沒有)的資料集。
- SELECT
- *
- FROM
- test_a
- FULL OUTER JOIN test_b ON test_a.name = test_b.name
- WHERE
- test_a.name IS NULL
- OR test_b.name IS NULL
H. cross join
表A和表B的資料進行一個N*M的組合,即笛卡爾積(交差集)。一般來說,我們很少用到這個文法。因為這種集合的使用對于性能來說非常危險,尤其是表很大。這裡就不做介紹了…
最後總結一下;
1.INNER JOIN 産生的結果是AB的交集
2.LEFT [OUTER] JOIN 産生表A的完全集,而B表中比對的則有值,沒有比對的則以null值取代。
3.RIGHT [OUTER] JOIN 産生表B的完全集,而A表中比對的則有值,沒有比對的則以null值取代。
4.FULL [OUTER] JOIN 産生A和B的并集。對于沒有比對的記錄,則會以null做為值。
5. CROSS JOIN 把表A和表B的資料進行一個N*M的組合,即笛卡爾積。産生N*M條記錄,在開發過程中我們肯定是要過濾資料,是以這種很少用。