1.LEFT JOIN 容易讓人誤解的地方
背景:因為在網上搜了下 LEFT JOIN 和 OUTER APPLY 的區別,時發現,有的網友解釋為:
1) A left join B 的連接的記錄數與A表的記錄數同.
2) LEFT JOIN 左連接 -- 顯示左表所有存在的記錄 記錄數=左表.
像這些說法都不對的.根據我測試得出的結論應該是:
LEFT JOIN 返回結果數 >= 左表的記錄數
網上有部分人的解釋都漏了 大於(>) 的那部分,后我找了下感覺比較權威的答案:
在W3School中的解釋為:
LEFT JOIN 關鍵字會從左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中沒有匹配的行。
在百度百科解釋為:
left join是以A表的記錄為基礎的,A可以看成左表,B可以看成右表,left join是以左表為准的。換句話說,左表(A)的記錄將會全部表示出來,而右表(B)只會顯示符合搜索條件的記錄(例子中為: A.aID = B.bID)。B表記錄不足的地方均為NULL。
好像都沒有明顯的說到:當左表的數據,在右表匹配到多條記錄的情況,這樣就很容易讓人誤解.下面我做了個例子,
比如有個類別表(Category)內容如下:
還有個類別明細表(CategoryDetail)內容如下:
那好現在測試開始:
可以看到,本來左表(Category)里面只有三條數據的,使用了LEFT JOIN之后帶出了四條數據,其中多出的就是對應左表(Category)匹配右表(CategoryDetail)數據時,出現多條數據的情況.
2.使用各種 JOIN 時需要注意的地方
一般我們使用JOIN 時都是直接一個表名, ON 后面加條件如下:
但是有時候也會這么寫:
這時候好像沒什么問題,好的,要是再加個條件 把兩個表關聯起來,那么問題來了,假如我是這樣寫:
1 SELECT * FROM dbo.Category a 2 LEFT JOIN (SELECT * FROM dbo.CategoryDetail b WHERE b.Id=1 AND b.CategoryId=a.Id) AS c ON 1=1
這時候就就會很郁悶的發現報錯了,報錯如下:
為什么會出現: 無法繫結多重部分(Multi-Part) 識別碼"a.Id"。 錯呢?我發現凡是適用JOIN時使用 括號() 然后在里面加select 語句時如果在使用外面的字段,就會報這個問題:
比如使用CROSS JOIN:
使用RIGHT JOIN:
使用INNER JOIN:
使用FULL JOIN:
總結:使用JOIN關鍵字時,如果不是直接JOIN一個表名而是,使用圓括號() 里面加select 語句時,關聯外部表字段時,就會出現: 無法繫結多重部分(Multi-Part) 識別碼 問題.
附注
附帶SQL腳本一份:

1 /****** Object: Table [dbo].[CategoryDetail] Script Date: 08/19/2015 19:46:37 ******/ 2 SET ANSI_NULLS ON 3 GO 4 SET QUOTED_IDENTIFIER ON 5 GO 6 SET ANSI_PADDING ON 7 GO 8 CREATE TABLE [dbo].[CategoryDetail]( 9 [Id] [int] IDENTITY(1,1) NOT NULL, 10 [CategoryId] [int] NULL, 11 [Cry] [varchar](50) NULL, 12 CONSTRAINT [PK_CategoryDetail] PRIMARY KEY CLUSTERED 13 ( 14 [Id] ASC 15 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 16 ) ON [PRIMARY] 17 GO 18 SET ANSI_PADDING OFF 19 GO 20 SET IDENTITY_INSERT [dbo].[CategoryDetail] ON 21 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (1, 1, N'喵') 22 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (2, 2, N'汪') 23 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (3, 2, N'汪汪') 24 SET IDENTITY_INSERT [dbo].[CategoryDetail] OFF 25 /****** Object: Table [dbo].[Category] Script Date: 08/19/2015 19:46:36 ******/ 26 SET ANSI_NULLS ON 27 GO 28 SET QUOTED_IDENTIFIER ON 29 GO 30 SET ANSI_PADDING ON 31 GO 32 CREATE TABLE [dbo].[Category]( 33 [Id] [int] IDENTITY(1,1) NOT NULL, 34 [Name] [varchar](50) NULL, 35 CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED 36 ( 37 [Id] ASC 38 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 39 ) ON [PRIMARY] 40 GO 41 SET ANSI_PADDING OFF 42 GO 43 SET IDENTITY_INSERT [dbo].[Category] ON 44 INSERT [dbo].[Category] ([Id], [Name]) VALUES (1, N'Cat') 45 INSERT [dbo].[Category] ([Id], [Name]) VALUES (2, N'Dog') 46 INSERT [dbo].[Category] ([Id], [Name]) VALUES (3, N'Tiger') 47 SET IDENTITY_INSERT [dbo].[Category] OFF