SQL Server 一些關鍵字詳解(二)


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
View Code

 

 

 

 

 

 

 

 

 


免責聲明!

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



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