先看看语法:

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

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

A1:把右表表达式(<right_table_expression>)应用到左表(<left_table_expression>)输入的行

A2:添加外部行;

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

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

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

看到上面的解释或步骤大家可能还是一头的雾水,不知所云。

下面用例子来说明:

--表一([dbo].[Customers]  字段说明:customerid--消费者id, city -- 所在城市):
CREATE TABLE [dbo].[Customers](
[customerid][char](5)NOTNULL,
[city][varchar](10)NOTNULL,
PRIMARY KEY CLUSTERED ( [customerid]ASC)WITH(IGNORE_DUP_KEY=OFF)ON [PRIMARY]
) ON [PRIMARY]
--向表一插入数据:
insert into dbo.Customersvalues('FISSA','Madrid');
insert into dbo.Customersvalues('FRNDO','Madrid');
insert into dbo.Customersvalues('KRLOS','Madrid');
insert into dbo.Customersvalues('MRPHS','Zion');
--表二([dbo].[Orders] 字段说明:orderid--订单id ,customerid -- 消费者id):
CREATE TABLE [dbo].[Orders](
[orderid] [int]NOT NULL,
[customerid][char](5)NULL,
PRIMARY KEY CLUSTERED ([orderid]ASC)WITH(IGNORE_DUP_KEY=OFF)ON [PRIMARY]
) ON [PRIMARY]
--向表二插入数据:
insert into dbo.Ordersvalues(1,'FRNDO');
insert into dbo.Ordersvalues(2,'FRNDO');
insert into dbo.Ordersvalues(3,'KRLOS');
insert into dbo.Ordersvalues(4,'KRLOS');
insert into dbo.Ordersvalues(5,'KRLOS');
insert into dbo.Ordersvalues(6,'MRPHS');
insert into dbo.Ordersvalues(7,null);
--查询插入的数据:
select *from dbo.Customers
select *from dbo.orders
结果:
customerid city
---------- ----------
FISSA Madrid
FRNDO Madrid
KRLOS Madrid
MRPHS Zion (4 行受影响) orderid customerid
----------- ----------
1 FRNDO
2 FRNDO
3 KRLOS
4 KRLOS
5 KRLOS
6 MRPHS
7 NULL (7 行受影响)

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

1、用cross apply

SELECT  *
FROM dbo.CustomersAS A
CROSS APPLY( SELECT TOP 2 *
FROM dbo.OrdersAS B
WHERE A.customerid= B.customerid
ORDER BY orderid DESC
) AS AB;

结果:

customerid city       orderid     customerid
---------- ---------- ---------------------
FRNDO Madrid 2 FRNDO
FRNDO Madrid 1 FRNDO
KRLOS Madrid 5 KRLOS
KRLOS Madrid 4 KRLOS
MRPHS Zion 6 MRPHS

过程分析:

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

2、用outer apply

SELECT  *
FROM dbo.CustomersAS A
OUTER APPLY( SELECT TOP 2
*
FROM dbo.OrdersAS B
WHERE A.customerid= B.customerid
ORDER BY orderid DESC
) AS AB;

结果:

customerid city       orderid     customerid
---------- ---------- ---------------------
FISSA Madrid NULL NULL
FRNDO Madrid 2 FRNDO
FRNDO Madrid 1 FRNDO
KRLOS Madrid 5 KRLOS
KRLOS Madrid 4 KRLOS
MRPHS Zion 6 MRPHS

结果分析:

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

【例二】

;with tb1(客户号,销售日期,销售额)AS(
select '001','2017-05-01',460 union all
select '001','2017-05-02',240 union all
select '001','2017-05-03',300
),TB2(客户号,付款额)AS(
select '001',500
)
SELECT t1.客户号 ,
t1.销售日期 ,
t1.销售额 ,
CASE WHEN t2.付款额 <= ISNULL(tt1.p_销售额, 0) THEN 0
ELSE CASE WHEN ( ISNULL(p_销售额, 0) + t1.销售额 ) >= t2.付款额
THEN t2.付款额 - ISNULL(p_销售额, 0)
ELSE t1.销售额
END
END AS 实付额
FROM tb1 AS t1
CROSS APPLY ( SELECT SUM(付款额) AS 付款额
FROM TB2
WHERE TB2.客户号 = t1.客户号
) AS t2
OUTER APPLY ( SELECT SUM(销售额) AS p_销售额
FROM tb1 AS tt
WHERE tt.客户号 = t1.客户号
AND tt.销售日期 < t1.销售日期
) AS tt1; --结果
客户号 销售日期 销售额 实付额
---- ---------- ----------- -----------
001 2017-05-01 460 460
001 2017-05-02 240 40
001 2017-05-03 300 0

SQL Server 关于CROSS APPLY 和 OUTER APPLY应用的更多相关文章

  1. SQL Server中CROSS APPLY和OUTER APPLY的应用详解

    SQL Server数据库操作中,在2005以上的版本新增加了一个APPLY表运算符的功能.新增的APPLY表运算符把右表表达式应用到左表表达式中的每一行.它不像JOIN那样先计算那个表表达式都可以, ...

  2. SQL Server连接查询之Cross Apply和Outer Apply的区别及用法(转载)

    先简单了解下cross apply的语法以及会产生什么样的结果集吧!示例表: SELECT * FROM tableA CROSS APPLY tableB 两张表直接连接,不需要任何的关联条件,产生 ...

  3. &lt;转&gt;SQL Server CROSS APPLY and OUTER APPLY

    Problem SQL Server 2005 introduced the APPLY operator, which is like a join clause and it allows joi ...

  4. SQL Server中CROSS APPLY和OUTER APPLY应用

    1.什么是Cross Apply和Outer Apply ? 我们知道SQL Server 2000中有Cross Join用于交叉联接的.实际上增加Cross Apply和Outer Apply是用 ...

  5. SQL SERVER使用 CROSS APPLY 与 OUTER APPLY 连接查询

    概述 CROSS APPLY 与 OUTER APPLY 可以做到:      左表一条关联右表多条记录时,我需要控制右表的某一条或多条记录跟左表匹配的情况. 有两张表:Student(学生表)和 S ...

  6. SQL 关于apply的两种形式cross apply 和 outer apply

    SQL 关于apply的两种形式cross apply 和 outer apply 例子: CREATE TABLE [dbo].[Customers]( ) COLLATE Chinese_PRC_ ...

  7. SQL 关于apply的两种形式cross apply 和 outer apply(转)

    转载链接:http://www.cnblogs.com/shuangnet/archive/2013/04/02/2995798.html apply有两种形式: cross apply 和 oute ...

  8. SQL关于apply的两种形式cross apply和outer apply(转载)

    SQL 关于apply的两种形式cross apply 和 outer apply   apply有两种形式: cross apply 和 outer apply   先看看语法:   <lef ...

  9. 转:SQL 关于apply的两种形式cross apply 和 outer apply

    原文地址:http://www.cnblogs.com/Leo_wl/archive/2013/04/02/2997012.html SQL 关于apply的两种形式cross apply 和 out ...

随机推荐

  1. 解剖SQLSERVER 完结篇 关于Internals Viewer源代码

    解剖SQLSERVER 完结篇 关于Internals Viewer源代码 大家可能都用过Internals Viewer这个软件 <查看SQLSERVER内部数据页面的小插件Internals ...

  2. .NET Core创建一个控制台(Console)程序

    .NET Core版本:1.0.0-rc2 Visual Studio版本:Microsoft Visual Studio Community 2015 Update 2 开发及运行平台:Window ...

  3. maven--composer---setting.xml(updatepolicy)---mvn install , mvn deploy

    场景:最近再整系统的自动部署流程,由于公司的jar包在svn以及mvn的仓库上都存在,开发人员在开发的过程中都依赖mvn仓库中的Jar 包,在jar上线的时候,配置管理人员把jar 从svn管理的工作 ...

  4. 使用pt-heartbeat检测主从复制延迟

    不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间,原因如下: A:备库Seconds_behand_master值是通过将服务器当前的时间戳与二进制日志中的事件的时间戳对 ...

  5. iptable软路由

    http://xstarcd.github.io/wiki/Linux/iptables_forward_internetshare.html # 默认丢弃转发,所有内网流量不能访问外网卡 iptab ...

  6. centos7 搭建docker内运行rabbitmq,然后再镜像ha方案的完全教程,暂时一个宿主机只能运行一个docker的rabbitmq,但是集群 ha都正常

    1.安装centos7.x,配置好网络2.因为docker需要比较高版本的内核,比如使用overlayfs作为默认docker文件系统要3.18,所以先升级内核到3.18以上版本,能直接过4是最佳了检 ...

  7. GNU风格 汇编语法总结(转)

    转载自:http://blog.sina.com.cn/s/blog_78d30f6b0101713r.html 汇编源程序一般用于系统最基本的初始化:初始化堆栈指针.设置页表.操作 ARM的协处理器 ...

  8. pktgen使用详细教程

    网上有很多讲解pktgen的文章,但总是不够全面细致,看完之后自己还是不会写pktgen测试脚本,为此本文对pktgen进行详细的阐述,让大家看完本文后能够自己动手写pktgen shell. 1.p ...

  9. android入门——Service

    简单记录一下四大组件之一的Service的简单实用. 先是最简单的用法,服务的开关,onBind方法的使用 package com.example.wkp.service; import androi ...

  10. 浅谈前后端分离与实践 之 nodejs 中间层服务(二)

    一.背景 书接上文,浅谈前后端分离与实践(一) 我们用mock服务器搭建起来了自己的前端数据模拟服务,前后端开发过程中只需定义好接口规范,便可以相互进行各自的开发任务.联调的时候,按照之前定义的开发规 ...