sqlserver中cross apply与outer apply用法

sqlserver中cross apply与outer apply用法apply有两种形式:crossapply和outerapply先看看语法:  <left_table_expression>{cross|outer}apply<right_table_expression>再让我们了解一下apply运算涉及的两个步骤:A1:把右表表达式(<right_table_expression>)应用…

apply有两种形式: cross apply 和 outer apply

先看看语法:

  <left_table_expression>  {cross|outer} apply <right_table_expression>

再让我们了解一下apply运算涉及的两个步骤:

  1. A1:把右表表达式(<right_table_expression>)应用到左表(<left_table_expression>)输入的行;
  2. A2:添加外部行;

  使用apply就像是先计算左输入,让后为左输入中的每一行计算一次右输入。(这一句很重要,可能会不理解,但要先记住,后面会有详细的说明)

最后结合以上两个步骤说明cross apply和outer apply的区别:

  cross apply和outer apply 总是包含步骤A1,只有outer apply包含步骤A2,如果cross apply左行应用右表表达式时返回空积,则不返回该行。而outer apply返回改行,并且改行的右表表达式的属性为null。

看到上面的解释或步骤大家可能还是一头的雾水,不知所云。下面用例子来说明:

先建表一([dbo].[Customers]  字段说明:customerid — 消费者id , city — 所在城市):

 

复制代码

复制代码

CREATE TABLE [dbo].[Customers](
    [customerid] [char](5) COLLATE Chinese_PRC_CI_AS NOT NULL,
    [city] [varchar](10) COLLATE Chinese_PRC_CI_AS NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [customerid] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

复制代码

复制代码

 

向表一插入数据:

insert into dbo.Customers values('FISSA','Madrid');
insert into dbo.Customers values('FRNDO','Madrid');
insert into dbo.Customers values('KRLOS','Madrid');
insert into dbo.Customers values('MRPHS','Zion');

查询所插入的数据:

select * from dbo.Customers

结果如图:

sqlserver中cross apply与outer apply用法

再建表二([dbo].[Orders]  字段说明:orderid — 订单id  , customerid — 消费者id):

复制代码

复制代码

CREATE TABLE [dbo].[Orders](
    [orderid] [int] NOT NULL,
    [customerid] [char](5) COLLATE Chinese_PRC_CI_AS NULL,
PRIMARY KEY CLUSTERED 
(
    [orderid] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

复制代码

复制代码

向表二插入数据:

复制代码

复制代码

insert into dbo.Orders values(1,'FRNDO');
insert into dbo.Orders values(2,'FRNDO');
insert into dbo.Orders values(3,'KRLOS');
insert into dbo.Orders values(4,'KRLOS');
insert into dbo.Orders values(5,'KRLOS');
insert into dbo.Orders values(6,'MRPHS');
insert into dbo.Orders values(7,null);

复制代码

复制代码

查询插入的数据:

select * from dbo.orders

结果如图:

sqlserver中cross apply与outer apply用法

例子:题目:得到每个消费者最新的两个订单:

用cross apply

sql:

复制代码

复制代码

select *
from dbo.Customers as C
 cross apply
    (select top 2 *
     from dbo.Orders as O
     where C.customerid=O.customerid
     order by orderid desc) as CA

复制代码

复制代码

结果如图:

sqlserver中cross apply与outer apply用法

过程分析:

  它是先得出左表【dbo.Customers】里的数据,然后把此数据一条一条的放入右表表式中,分别得出结果集,最后把结果集整合到一起就是最终的返回结果集了(T1的数据 像for循环一样 一条一条的进入到T2中 然后返回一个集合  最后把所有的集合整合到一块  就是最终的结果),最后我们再理解一下上面让记着的话(使用apply就像是先计算左输入,让后为左输入中的每一行计算一次右输入)是不是有所明白了。

实验:用outer apply 试试看看的到的结果:

sql语句:

复制代码

复制代码

select *
from dbo.Customers as C
 outer apply
    (select top 2 *
     from dbo.Orders as O
     where C.customerid=O.customerid
     order by orderid desc) as CA

复制代码

复制代码

结果如图:

sqlserver中cross apply与outer apply用法

结果分析:

  发现outer apply得到的结果比cross多了一行,我们结合上面所写的区别(cross apply和outer apply 总是包含步骤A1,只有outer apply包含步骤A2,如果cross apply左行应用右表表达式时返回空积,则不返回该行。而outer apply返回改行,并且改行的右表表达式的属性为null)就会知道了。

 

 

回到目录

Sql学习第四天——SQL 关于with cube ,with rollup 和 grouping

关于with cube ,with rollup 和 grouping

通过查看sql 2005的帮助文档找到了CUBE 和 ROLLUP 之间的具体区别:

  1. CUBE 生成的结果集显示了所选列中值的所有组合的聚合。
  2. ROLLUP 生成的结果集显示了所选列中值的某一层次结构的聚合。

再看看对grouping的解释:

  当行由 CUBE 或 ROLLUP 运算符添加时,该函数将导致附加列的输出值为 1;当行不由 CUBE 或 ROLLUP 运算符添加时,该函数将导致附加列的输出值为 0。

仅在与包含 CUBE 或 ROLLUP 运算符的 GROUP BY 子句相关联的选择列表中才允许分组。

当看到以上的解释肯定非常的模糊,不知所云和不知道该怎样用,下面通过实例操作来体验一下:

先建表(dbo.PeopleInfo):

复制代码

复制代码

CREATE TABLE [dbo].[PeopleInfo](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [name] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,
    [numb] [nchar](10) COLLATE Chinese_PRC_CI_AS NOT NULL,
    [phone] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,
    [FenShu] [int] NULL
) ON [PRIMARY]

复制代码

复制代码

向表插入数据:

复制代码

insert into peopleinfo([name],numb,phone,fenshu) values ('李欢','3223','1365255',80)
insert into peopleinfo([name],numb,phone,fenshu) values ('李欢','322123','1',90)
insert into peopleinfo([name],numb,phone,fenshu) values ('李名','3213112352','13152',56)
insert into peopleinfo([name],numb,phone,fenshu) values ('李名','32132312','13342563',60)
insert into peopleinfo([name],numb,phone,fenshu) values ('王华','3223','1365255',80)

复制代码

查询出插入的全部数据:

select * from dbo.PeopleInfo

结果如图:

sqlserver中cross apply与outer apply用法

操作一:先试试:1, 查询所有数据;2,用group by 查询所有数据;3,用with cube。这三种情况的比较

SQL语句如下:

复制代码

select * from dbo.PeopleInfo                                                        --1, 查询所有数据;

select [name],numb,sum(fenshu) from dbo.PeopleInfo group by [name],numb             --2,用group by 查询所有数据;

select [name],numb,sum(fenshu) from dbo.PeopleInfo group by [name],numb with cube   --3,用with cube。这三种情况的比较

复制代码

结果如图:

sqlserver中cross apply与outer apply用法

结果分析:

  用第三种(用with cube)为什么会多出来有null的字段值呢?通过分析图上的值得组合会发现是怎么回事儿了,以第三条数据(李欢,null,170)为例:它只是把姓名是【李欢】的分为了一组,而没有考虑【numb】,所以有多出来了第三条数据,也说明了170是怎么来的。其他的也是这样。再回顾一下帮助文档的解释:CUBE 生成的结果集显示了所选列中值的所有组合的聚合, 发现明了了许多。

操作二:1,用with cube;2,用with rollup 这两种情况的比较

SQL语句如下:

select [name],numb,sum(fenshu) from dbo.PeopleInfo group by [name],numb with cube    --用with cube。

select [name],numb,sum(fenshu) from dbo.PeopleInfo group by [name],numb with rollup  --用with rollup。

结果如图:

sqlserver中cross apply与outer apply用法

结果分析:

  为什么with cube 比 with rollup多出来一部分呢?原来它没有显示,以【numb】分组而不考虑【name】的数据情况。再回顾一下帮助文档的解释:ROLLUP 生成的结果集显示了所选列中值的某一层次结构的聚合,那这个【某一层次】又是以什么为标准的呢?我的猜想是:距离group up最近的字段必须考虑在分组内。

证明猜想实例:

操作:用两个group up 交换字段位置的sql语句和一个在group up 后面增加一个字段的sql语句进行比较:

SQL语句如下:

 

复制代码

select [name],numb from dbo.PeopleInfo group by [name],numb with rollup

select [name],numb from dbo.PeopleInfo group by numb,[name] with rollup

select [name],numb,phone from dbo.PeopleInfo group by [name],numb,phone with rollup

复制代码

 

结果如图:

sqlserver中cross apply与outer apply用法sqlserver中cross apply与outer apply用法

通过结果图的比较发现猜想是正确的。

—————————————————grouping————————————————-

现在来看看grouping的实例:

SQL语句看看与with rollup的结合(与with cube的结合是一样的):

select [name],numb,grouping(numb) from dbo.PeopleInfo group by [name],numb with rollup

结果如图:

sqlserver中cross apply与outer apply用法

结果分析:

  结合帮助文档的解释:当行由 CUBE 或 ROLLUP 运算符添加时,该函数将导致附加列的输出值为 1;当行不由 CUBE 或 ROLLUP 运算符添加时,该函数将导致附加列的输出值为 0。  很容易理解再此就不多解释了。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/234627.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • 织梦中data文件夹是存放什么内容的

    织梦中data文件夹是存放什么内容的

    2021年10月7日
  • 神奇的罗斯.布朗_罗曼·格罗斯让

    神奇的罗斯.布朗_罗曼·格罗斯让这是一篇赞美罗斯.布朗和他的车队布朗GP的文章未完,抽时间写作中……转载于:https://www.cnblogs.com/yuuhhe/archive/2009/03/30/1425074.html

    2022年9月30日
  • 不会真有人Macbook录屏没声音吧?别用SoundFlower了!

    不会真有人Macbook录屏没声音吧?别用SoundFlower了!录屏顺便一提:shift+command+3:截整个屏幕shift+command+4:截所选区域shift+command+5:录屏Loopback可以把内置声音录进去,且音质很顶,且录屏的时候,你可以听得到声音。loopback官网先跟着我这么着配置一下,英语看不懂不用怕,有我在没意外。然后,按shift+command+5,底部会出现那个条条框。然后,先选好是录整个屏幕还是录一部分。然后,点选项,把麦克风那部分选成Loopback开头的那个选项。然后,点击录制,就完了。然

    2022年5月31日
  • mac redis安装_如何启动redis

    mac redis安装_如何启动redisMac安装Redis,原来就是这么简单_MarkJava-CSDN博客_mac安装redis注意:安装brew之前需要切换到普通用户,命令为su用户名。如果在root用户模式下安装报错

    2022年11月3日
  • arcgis入门到精通视频教程下载连接[通俗易懂]

    arcgis入门到精通视频教程下载连接[通俗易懂]04空间数据Coverage的创建.wmv05空间数据Geodatabase数据库创建.wmv06空间可视化工具ArcMap.wmv07空间数据编辑.avi08空间数据的转换.wmv09空间数据的处理.wmv10空与制图间数据的可视化.wmv11空间分析工具.wmv12ArcGIS矢量数据的空间分析.wmv13Arcgis栅格数据的空间分析.wmv14-1ArcGIS三维分析.

    2022年6月15日
  • Linux 搭建 Kafka教程[通俗易懂]

    Linux 搭建 Kafka教程[通俗易懂]把kafka解压到linux去配置文件中配置环境配置kafka文件内容进入kafka/config目录修改server.properties文件修改broker.id=id里面的数值不可以重复同时添加主机的ip和端口host.name=192.168.10.101listeners=PLAINTEXT://192.168.10.101:9092在下面找到log.dirs修改日志的地址修改为我们三台机器ip地址zookeeper.connect=localhost:21

    2022年10月16日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号