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

例子:

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 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 --得到每个消费者最新的两个订单:
--用cross apply 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 --过程分析:
--它是先得出左表【dbo.Customers】里的数据,然后把此数据一条一条的放入右表表式中,分别得出结果集,最后把结果集整合到一起就是最终的返回结果集了
--(T1的数据 像for循环一样 一条一条的进入到T2中 然后返回一个集合 最后把所有的集合整合到一块 就是最终的结果),
--最后我们再理解一下上面让记着的话(使用apply就像是先计算左输入,让后为左输入中的每一行计算一次右输入)是不是有所明白了。
--实验:用outer apply 试试看看的到的结果: 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 --结果分析:
--发现outer apply得到的结果比cross多了一行,我们结合上面所写的区别(cross apply和outer apply 总是包含步骤A1,只有outer apply包含步骤A2,
--如果cross apply左行应用右表表达式时返回空积,则不返回该行。而outer apply返回改行,并且改行的右表表达式的属性为null)就会知道了。

例子:

--下面是完整的测试代码,你可以在 SQL Server 2005 联机帮助上找到: 

-- create Employees table and insert values
IF OBJECT_ID('Employees') IS NOT NULL
DROP TABLE Employees
GO
CREATE TABLE Employees
(
empid INT NOT NULL,
mgrid INT NULL,
empname VARCHAR(25) NOT NULL,
salary MONEY NOT NULL
)
GO
IF OBJECT_ID('Departments') IS NOT NULL
DROP TABLE Departments
GO
-- create Departments table and insert values
CREATE TABLE Departments
(
deptid INT NOT NULL PRIMARY KEY,
deptname VARCHAR(25) NOT NULL,
deptmgrid INT
)
GO -- fill datas
INSERT INTO employees VALUES (1,NULL,'Nancy',00.00)
INSERT INTO employees VALUES (2,1,'Andrew',00.00)
INSERT INTO employees VALUES (3,1,'Janet',00.00)
INSERT INTO employees VALUES (4,1,'Margaret',00.00)
INSERT INTO employees VALUES (5,2,'Steven',00.00)
INSERT INTO employees VALUES (6,2,'Michael',00.00)
INSERT INTO employees VALUES (7,3,'Robert',00.00)
INSERT INTO employees VALUES (8,3,'Laura',00.00)
INSERT INTO employees VALUES (9,3,'Ann',00.00)
INSERT INTO employees VALUES (10,4,'Ina',00.00)
INSERT INTO employees VALUES (11,7,'David',00.00)
INSERT INTO employees VALUES (12,7,'Ron',00.00)
INSERT INTO employees VALUES (13,7,'Dan',00.00)
INSERT INTO employees VALUES (14,11,'James',00.00) INSERT INTO departments VALUES (1,'HR',2)
INSERT INTO departments VALUES (2,'Marketing',7)
INSERT INTO departments VALUES (3,'Finance',8)
INSERT INTO departments VALUES (4,'R&D',9)
INSERT INTO departments VALUES (5,'Training',4)
INSERT INTO departments VALUES (6,'Gardening',NULL)
GO
--SELECT * FROM departments -- table-value function
IF OBJECT_ID('fn_getsubtree') IS NOT NULL
DROP FUNCTION fn_getsubtree
GO
CREATE FUNCTION dbo.fn_getsubtree(@empid AS INT)
RETURNS TABLE
AS
RETURN(
WITH Employees_Subtree(empid, empname, mgrid, lvl)
AS
(
-- Anchor Member (AM)
SELECT empid, empname, mgrid, 0
FROM employees
WHERE empid = @empid
UNION ALL
-- Recursive Member (RM)
SELECT e.empid, e.empname, e.mgrid, es.lvl+1
FROM employees AS e
join employees_subtree AS es
ON e.mgrid = es.empid
)
SELECT * FROM Employees_Subtree
)
GO -- cross apply query
SELECT *
FROM Departments AS D
CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST -- outer apply query
SELECT *
FROM Departments AS D
OUTER APPLY fn_getsubtree(D.deptmgrid) AS ST select * from employees
select * from Departments select * from fn_getsubtree(2)
select * from fn_getsubtree(3)
select * from fn_getsubtree(4)
select * from fn_getsubtree(5)
select * from fn_getsubtree(6)

例子:

create table #T(姓名 varchar(10))
insert into #T values('张三')
insert into #T values('李四')
insert into #T values(NULL ) create table #T2(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
insert into #T2 values('张三' , '语文' , 74)
insert into #T2 values('张三' , '数学' , 83)
insert into #T2 values('张三' , '物理' , 93)
insert into #T2 values(NULL , '数学' , 50) --drop table #t,#T2
go select
*
from
#T a
cross apply
(select 课程,分数 from #t2 where 姓名=a.姓名) b /*
姓名 课程 分数
---------- ---------- -----------
张三 语文 74
张三 数学 83
张三 物理 93 (3 行受影响) */ select
*
from
#T a
outer apply
(select 课程,分数 from #t2 where 姓名=a.姓名) b
/*
姓名 课程 分数
---------- ---------- -----------
张三 语文 74
张三 数学 83
张三 物理 93
李四 NULL NULL
NULL NULL NULL (5 行受影响) */

SQL 关于apply的两种形式cross apply 和 outer apply的更多相关文章

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

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

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

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

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

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

  4. SQL 关于apply的两种形式cross apply 和 outer apply, with cube 、with rollup 和 grouping

    1). apply有两种形式: cross apply 和 outer apply先看看语法: <left_table_expression> {cross|outer} apply &l ...

  5. C# ASP.NET(配置数据库 sql server 地址的两种形式以及配置信息的获取)

    ( 1 ) 数据库装在本机,并且采用windows认证模式 <connectionStrings>    <add name="SQLConnectionString&qu ...

  6. 在sql中case子句的两种形式

    case子句,在select后面可以进行逻辑判断. 两种形式:判断相等.判断不等 一.判断相等的语法: case 列名 when ...  then ... when ...  then ... el ...

  7. MyBatis collection的两种形式——MyBatis学习笔记之九

    与association一样,collection元素也有两种形式,现介绍如下: 一.嵌套的resultMap 实际上以前的示例使用的就是这种方法,今天介绍它的另一种写法.还是以教师映射为例,修改映射 ...

  8. 基于 Scrapy-redis 两种形式的分布式爬虫

    基于 Scrapy-redis 两种形式的分布式爬虫 .caret, .dropup > .btn > .caret { border-top-color: #000 !important ...

  9. C++:一般情况下,设计函数的形参只需要两种形式

    C++:一般情况下,设计函数的形参只需要两种形式.一,是引用形参,例如 void function (int &p_para):二,是常量引用形参,例如 void function(const ...

随机推荐

  1. RabbitMQ 入门

    简介   RabbitMQ是一个Message Broker,核心思想就是接受消息,转发消息. 实现的协议:AMQP.   术语(Jargon)   P,Producing,制造和发送信息的一方. Q ...

  2. Log4j2常见使用示例及Syslog/Syslog-ng

    准备工作 打开http://logging.apache.org/log4j/,点击左侧Download,我下载的是Apache Log4j 2 binary (zip),目前是2.0.2版本.解压后 ...

  3. iis 故障导致网站无法访问

    服务器使用两三个月突然,昨天无法访问,重启后正常,第二次发生这样的事情了,打开  C:\WINDOWS\system32\LogFiles\HTTPERR  下的   httperr1.txt 201 ...

  4. 【资源集合】94个iOS开发资源推荐,帮你加速应用开发

    资源总结类文章总是开发者们所喜欢的,网上已经有各种weekly.头条以及期刊类资源总结,今天这篇来自于开发者Viswateja Reddy的总结.原文对各个项目的介绍非常简单,为了更便于阅读,编辑在原 ...

  5. ios app 提交评审注意事项

    在网络上看到的一个文档是这样写,原文的出处无法确认了 基本要点 ·         不能导致手机故障(比如崩溃或屏幕问题) ·         长时间/过度使用之后反应仍然很快 ·         应 ...

  6. object-c学习1

    因为公司需要,开始看object-c,虽然还没ios系统,但现学下语法. 第一个例子不应该是helloWorld吗?但<Learn Objective-C on the Mac>书上不是. ...

  7. Eclipse中web项目缓存路径

    eclipse运行web项目后, 默认保存到 workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps ecli ...

  8. linq to entity 获取项的集合总数

    IEnumerable<InspecReportsContextEntity> OnenewDate = lisConAll.Where(p => p.inspectime == t ...

  9. 定时从远程的数据库中取数据,然后把取出来的数据插入或更新本地的oracle数据库的表

    最近项目中有一种需求: 大致需求是这样的 通过给定的 用户名和密码 要定时从远程的数据库中取数据,然后把取出来的数据插入或更新本地的oracle数据库的表 项目的结构式struts1 hibernat ...

  10. LCLFramework架构必须要知道的知识

    技术实现: 代码是否面向对象,要看你的继承怎么用 用抽象来展现层次感 用接口来制定操作的统一性 依赖住入(Inversion of Control) Unit of Work Repository D ...