SQL 关于apply的两种形式cross apply 和 outer apply
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的更多相关文章
- SQL关于apply的两种形式cross apply和outer apply(转载)
SQL 关于apply的两种形式cross apply 和 outer apply apply有两种形式: cross apply 和 outer apply 先看看语法: <lef ...
- 转:SQL 关于apply的两种形式cross apply 和 outer apply
原文地址:http://www.cnblogs.com/Leo_wl/archive/2013/04/02/2997012.html SQL 关于apply的两种形式cross apply 和 out ...
- SQL 关于apply的两种形式cross apply 和 outer apply(转)
转载链接:http://www.cnblogs.com/shuangnet/archive/2013/04/02/2995798.html apply有两种形式: cross apply 和 oute ...
- SQL 关于apply的两种形式cross apply 和 outer apply, with cube 、with rollup 和 grouping
1). apply有两种形式: cross apply 和 outer apply先看看语法: <left_table_expression> {cross|outer} apply &l ...
- C# ASP.NET(配置数据库 sql server 地址的两种形式以及配置信息的获取)
( 1 ) 数据库装在本机,并且采用windows认证模式 <connectionStrings> <add name="SQLConnectionString&qu ...
- 在sql中case子句的两种形式
case子句,在select后面可以进行逻辑判断. 两种形式:判断相等.判断不等 一.判断相等的语法: case 列名 when ... then ... when ... then ... el ...
- MyBatis collection的两种形式——MyBatis学习笔记之九
与association一样,collection元素也有两种形式,现介绍如下: 一.嵌套的resultMap 实际上以前的示例使用的就是这种方法,今天介绍它的另一种写法.还是以教师映射为例,修改映射 ...
- 基于 Scrapy-redis 两种形式的分布式爬虫
基于 Scrapy-redis 两种形式的分布式爬虫 .caret, .dropup > .btn > .caret { border-top-color: #000 !important ...
- C++:一般情况下,设计函数的形参只需要两种形式
C++:一般情况下,设计函数的形参只需要两种形式.一,是引用形参,例如 void function (int &p_para):二,是常量引用形参,例如 void function(const ...
随机推荐
- 线程同步中使用信号量AutoResetEvent
using System; using System.Threading; namespace ConsoleApplication1 { class Program { static void Ma ...
- The main difference between Java & C++(转载)
转载自:http://stackoverflow.com/questions/9192309/the-main-difference-between-java-c C++ supports point ...
- Android屏幕适配的一些常识
屏幕适配的注意事项 1. AndroidManifest.xml设置 在中Menifest中添加子元素 android:anyDensity="true"时,应用程序安装在不同密度 ...
- Windows KB2984972安装后堵住了一个windows 7 桌面可以多个用户远程访问桌面的漏洞。
之前网络上有方法可以实现2个用户同时使用一个windows 7,一个在终端,一个通过远程桌面. 安装了这个kb后,就无法同时登陆了,同一时间只有一个用户可以登陆windows 7
- linux中ssh可以登录sftp不能登录解决办法
我的服务器一直正常使用,平时使用secureCRT进行管理,使用secureFX进行文件的上传下载,突然有一天secureFX连接的时候出问题了,secureFX的日志如下: i SecureFX 版 ...
- Android 中的AIDL,Parcelable和远程服务
Android 中的AIDL,Parcelable和远程服务 早期在学习期间便接触到AIDL,当时对此的运用也是一撇而过.只到近日在项目中接触到AIDL,才开始仔细深入.AIDL的作用 ...
- 少睡与吸烟影响IQ
导读:据英国<每日邮报>报道,根据科学家一项最新研究发现,一晚的糟糕睡眠,对大脑可能产生很大损害,就等同头部遭到了一次严重的撞击.长期睡眠不好会造成智力下降,请看[科学探索]揭秘: ...
- (笔记)Linux内核学习(十一)之I/O层和I/O调度机制
一 块I/O基本概念 字符设备:按照字符流的方式被有序访问的设备.如串口.键盘等. 块设备:系统中不能随机(不需要按顺序)访问固定大小的数据片(chunk 块)的设备. 如:硬盘.软盘.CD-ROM驱 ...
- C# 实现字符串去重
方法一 注:需要.net 3.5框架的支持 string s = "101,102,103,104,105,101,102,103,104,105,106,107,101,108" ...
- undercore & Backbone对AMD的支持(Require.js中如何使用undercore & Backbone)
RequireJS填补了前端模块化开发的空缺,RequireJS遵循AMD(异步模块定义,Asynchronous Module Definition)规范,越来越多的框架支持AMD,像最近的jQue ...