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相交的部分:
2.OUTERAPPLY和LEFTJOINLEFTJOIN关键字会从左表(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
新闻热点
疑难解答