• SQL Server 一些关键字详解(一)


    1.CROSS APPLY OUTER APPLY

    MSDN解释如下(个人理解不是很清晰):

    使用 APPLY 运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数。表值函数作为右输入,外部表表达式作为左输入。通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出。APPLY 运算符生成的列的列表是左输入中的列集,后跟右输入返回的列的列表。

    APPLY 有两种形式:CROSS APPLY 和 OUTER APPLYCROSS APPLY 仅返回外部表中通过表值函数生成结果集的行。OUTER APPLY 既返回生成结果集的行,也返回不生成结果集的行,其中表值函数生成的列中的值为 NULL

     

    网上搜集的解释如下(个人感觉好理解):

    SQL Server数据库操作中,在2005以上的版本新增加了一个APPLY表运算符的功能。新增的APPLY表运算符把右表表达式应用到左表表达式中的每一行。它不像JOIN那样先计算哪个表表达式都可以,APPLY必须先逻辑地计算左表达式。这种计算输入的逻辑顺序允许把右表达式关联到左表表达式。

    APPLY有两种形式,一个是OUTER APPLY,一个是CROSS APPLY,区别在于指定OUTER,意味着结果集中将包含使右表表达式为空的左表表达式中的行,而指定CROSS,则相反,结果集中不包含使右表表达式为空的左表表达式中的行

     

    注意:若要使用 APPLY,数据库兼容级别必须为 90

     

    下面我们做个例子:

    比如有个类别表(Category)内容如下:

     

    还有个类别明细表(CategoryDetail)内容如下:

     

     

    下面我们来看看OUTER APPLY 的查询结果:

    1 SELECT  *
    2 FROM    dbo.Category a
    3         OUTER APPLY ( SELECT    *
    4                       FROM      dbo.CategoryDetail b
    5                       WHERE     b.CategoryId = a.Id
    6                     ) AS c ;

    由上图可看出OUTER APPLY把左表中的信息查出后把右表中的信息也关联出来了,当然当右表的信息为空(NULL)时,OUTER APPLY也会在结果集中显示出来.

     

    接下来我们看下CROSS APPLY的查询结果:

    1 SELECT  *
    2 FROM    dbo.Category a
    3         CROSS APPLY ( SELECT    *
    4                       FROM      dbo.CategoryDetail b
    5                       WHERE     b.CategoryId = a.Id
    6                     ) AS c ;

    根据这图和上面的比较可看出,这个返回结果只有两个,Category 表中的Tiger的信息没有带出来,因为在CategoryDetail 表中没有对应的明细.

    由以上信息可得出,OUTER APPLY 就相当于数学中的并集,CROSS APPLY相当于数学中的交集,关于交集与并集的介绍如下:

    并集为下图中的所有红色部分,即为AB的全部:

    交集为下图中的红色部分,也就是AB相交的部分:

    2.OUTER APPLY LEFT JOIN

    LEFT JOIN 关键字会从左表 (Category) 那里返回所有的行,即使在右表 (CategoryDetail) 中没有匹配的行。

    注释:在某些数据库中, LEFT JOIN 称为 LEFT OUTER JOIN

     

    下面我们来看看LEFT JOIN 的查询结果(还是1.CROSS APPLY 和 OUTER APPLY中的例子):

    1 SELECT  *
    2 FROM    dbo.Category a
    3         LEFT JOIN dbo.CategoryDetail b ON b.CategoryId = a.Id ;
    View Code

    LEFT JOIN 关键字会从左表 (Category) 那里返回所有的行,即使在右表 (CategoryDetail) 中没有匹配的行。效果和OUTER APPLY 一样。

    OUTER APPLY 和 LEFT JOIN 的主要区别为:

      一个LEFT JOIN 关键字只能JOIN 一个表,不能解决一个复杂的SELECT 语句,或者函数方法等。

      一个OUTER APPLY 关键字可以包含一个独立的复杂的SELECT 语句,或者其他函数方法等。

     

    OUTER APPLY 和 LEFT JOIN 性能的区别:

      据这博客LEFT JOIN和OUTER APPLY性能比较的总结可知 LEFT JOIN 要比 OUTER APPLY 性能要快。所以建议能用LEFT JOIN的尽量不要用OUTER APPLY

     

    附注:

    附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 GO
    11 SET ANSI_PADDING OFF
    12 GO
    13 SET IDENTITY_INSERT [dbo].[CategoryDetail] ON
    14 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] OFF
    17 /****** Object:  Table [dbo].[Category]    Script Date: 08/17/2015 18:24:03 ******/
    18 SET ANSI_NULLS ON
    19 GO
    20 SET QUOTED_IDENTIFIER ON
    21 GO
    22 SET ANSI_PADDING ON
    23 GO
    24 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] ASC
    30 )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 GO
    33 SET ANSI_PADDING OFF
    34 GO
    35 SET IDENTITY_INSERT [dbo].[Category] ON
    36 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] OFF
    View Code
  • 相关阅读:
    JS实战 · 表单验证
    JS实战 · 仿css样式选择器
    JS实战 ·  收缩菜单表单布局
    cookie自动登录的实现
    redis 3.2.5单机版安装、使用、systemctl管理Redis启动、停止、开机启动
    yum问题解决
    配置yum镜像源
    shell笔记
    CCIE总结:路由器、交换机
    云主机如何挂在磁盘
  • 原文地址:https://www.cnblogs.com/lyaom/p/4737595.html
Copyright © 2020-2023  润新知