MSDN解釋如下(個人理解不是很清晰):
使用APPLY運算符可以為實現查詢操作的外部表表達式返回的每個行調用表值函數。表值函數作為右輸入,外部表表達式作為左輸入。通過對右輸入求值來獲得左輸入每一行的計算結果,生成的行被組合起來作為最終輸出。APPLY運算符生成的列的列表是左輸入中的列集,后跟右輸入返回的列的列表。
APPLY有兩種形式:CROSSAPPLY和OUTERAPPLY。CROSSAPPLY僅返回外部表中通過表值函數生成結果集的行。OUTERAPPLY既返回生成結果集的行,也返回不生成結果集的行,其中表值函數生成的列中的值為NULL。
網上搜集的解釋如下(個人感覺好理解):
SQLServer數據庫操作中,在2005以上的版本新增加了一個APPLY表運算符的功能。新增的APPLY表運算符把右表表達式應用到左表表達式中的每一行。它不像JOIN那樣先計算哪個表表達式都可以,APPLY必須先邏輯地計算左表達式。這種計算輸入的邏輯順序允許把右表達式關聯到左表表達式。
APPLY有兩種形式,一個是OUTERAPPLY,一個是CROSSAPPLY,區別在于指定OUTER,意味著結果集中將包含使右表表達式為空的左表表達式中的行,而指定CROSS,則相反,結果集中不包含使右表表達式為空的左表表達式中的行。
注意:若要使用APPLY,數據庫兼容級別必須為90。
下面我們做個例子:
比如有個類別表(Category)內容如下:
還有個類別明細表(CategoryDetail)內容如下:
下面我們來看看OUTERAPPLY的查詢結果:
1 SELECT *2 FROM dbo.Category a3 OUTER APPLY ( SELECT *4 FROM dbo.CategoryDetail b5 WHERE b.CategoryId = a.Id6 ) AS c ;
由上圖可看出OUTERAPPLY把左表中的信息查出后把右表中的信息也關聯出來了,當然當右表的信息為空(NULL)時,OUTERAPPLY也會在結果集中顯示出來.
接下來我們看下CROSSAPPLY的查詢結果:
1 SELECT *2 FROM dbo.Category a3 CROSS APPLY ( SELECT *4 FROM dbo.CategoryDetail b5 WHERE b.CategoryId = a.Id6 ) AS c ;
根據這圖和上面的比較可看出,這個返回結果只有兩個,Category表中的Tiger的信息沒有帶出來,因為在CategoryDetail表中沒有對應的明細.
由以上信息可得出,OUTERAPPLY就相當于數學中的并集,而CROSSAPPLY相當于數學中的交集,關于交集與并集的介紹如下:
并集為下圖中的所有紅色部分,即為A和B的全部:
交集為下圖中的紅色部分,也就是A和B相交的部分:
LEFTJOIN關鍵字會從左表(Category)那里返回所有的行,即使在右表(CategoryDetail)中沒有匹配的行。
注釋:在某些數據庫中,LEFTJOIN稱為LEFTOUTERJOIN。
下面我們來看看LEFTJOIN的查詢結果(還是1.CROSSAPPLY和OUTERAPPLY中的例子):
1 SELECT *2 FROM dbo.Category a3 LEFT JOIN dbo.CategoryDetail b ON b.CategoryId = a.Id ;View Code
LEFTJOIN關鍵字會從左表(Category)那里返回所有的行,即使在右表(CategoryDetail)中沒有匹配的行。效果和OUTERAPPLY一樣。
OUTERAPPLY和LEFTJOIN的主要區別為:
一個LEFTJOIN關鍵字只能JOIN一個表,不能解決一個復雜的SELECT語句,或者函數方法等。
一個OUTERAPPLY關鍵字可以包含一個獨立的復雜的SELECT語句,或者其他函數方法等。
OUTERAPPLY和LEFTJOIN性能的區別:
據這博客LEFTJOIN和OUTERAPPLY性能比較的總結可知LEFTJOIN要比OUTERAPPLY性能要快。所以建議能用LEFTJOIN的盡量不要用OUTERAPPLY。
附注:附Category表和CategoryDetail表的結果及插入數據的腳本:
1 CREATE TABLE [dbo].[CategoryDetail]( 2 [Id] [int] IDENTITY(1,1) NOT NULL, 3 [CategoryId] [int] NULL, 4 [Cry] [varchar](50) NULL, 5 CONSTRAINT [PK_CategoryDetail] PRIMARY KEY CLUSTERED 6 ( 7 [Id] ASC 8 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 9 ) ON [PRIMARY]10 GO11 SET ANSI_PADDING OFF12 GO13 SET IDENTITY_INSERT [dbo].[CategoryDetail] ON14 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (1, 1, N'喵')15 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (2, 2, N'汪')16 SET IDENTITY_INSERT [dbo].[CategoryDetail] OFF17 /****** Object: Table [dbo].[Category] Script Date: 08/17/2015 18:24:03 ******/18 SET ANSI_NULLS ON19 GO20 SET QUOTED_IDENTIFIER ON21 GO22 SET ANSI_PADDING ON23 GO24 CREATE TABLE [dbo].[Category](25 [Id] [int] IDENTITY(1,1) NOT NULL,26 [Name] [varchar](50) NULL,27 CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED 28 (29 [Id] ASC30 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]31 ) ON [PRIMARY]32 GO33 SET ANSI_PADDING OFF34 GO35 SET IDENTITY_INSERT [dbo].[Category] ON36 INSERT [dbo].[Category] ([Id], [Name]) VALUES (1, N'Cat')37 INSERT [dbo].[Category] ([Id], [Name]) VALUES (2, N'Dog')38 INSERT [dbo].[Category] ([Id], [Name]) VALUES (3, N'Tiger')39 SET IDENTITY_INSERT [dbo].[Category] OFFView Code
新聞熱點
疑難解答