SQL Server 2005 新增 cross apply 和 outer apply 联接语句,增加这两个东东有啥作用呢?
我们知道有个 SQL Server 2000 中有个 cross join 是用于交叉联接的。实际上增加 cross apply 和 outer apply 是用于交叉联接表值函数(返回表结果集的函数)的, 更重要的是这个函数的参数是另一个表中的字段。这个解释可能有些含混不请,请看下面的例子:
-- 1. cross join 联接两个表
select *
from TABLE_1 as T1
cross join TABLE_2 as T2
-- 2. cross join 联接表和表值函数,表值函数的参数是个“常量”
select *
from TABLE_1 T1
cross join FN_TableValue(100)
-- 3. cross join 联接表和表值函数,表值函数的参数是“表T1中的字段”
select *
from TABLE_1 T1
cross join FN_TableValue(T1.column_a)
Msg 4104, Level 16, State 1, Line 1
The multi-part identifier "T1.column_a" could not be bound.
最后的这个查询的语法有错误。在 cross join 时,表值函数的参数不能是表 T1 的字段, 为啥不能这样做呢?我猜可能微软当时没有加这个功能:),后来有客户抱怨后, 于是微软就增加了 cross apply 和 outer apply 来完善,请看 cross apply, outer apply 的例子:
-- 4. cross apply
select *
from TABLE_1 T1
cross apply FN_TableValue(T1.column_a)
-- 5. outer apply
select *
from TABLE_1 T1
outer apply FN_TableValue(T1.column_a)
cross apply 和 outer apply 对于 T1 中的每一行都和派生表(表值函数根据T1当前行数据生成的动态结果集) 做了一个交叉联接。cross apply 和 outer apply 的区别在于: 如果根据 T1 的某行数据生成的派生表为空,cross apply 后的结果集 就不包含 T1 中的这行数据,而 outer apply 仍会包含这行数据,并且派生表的所有字段值都为 NULL。
下面的例子摘自微软 SQL Server 2005 联机帮助,它很清楚的展现了 cross apply 和 outer apply 的不同之处:
-- cross apply
select *
from Departments as D
cross apply fn_getsubtree(D.deptmgrid) as ST
deptid deptname deptmgrid empid empname mgrid lvl
----------- ----------- ----------- ----------- ----------- ----------- ------
1 HR 2 2 Andrew 1 0
1 HR 2 5 Steven 2 1
1 HR 2 6 Michael 2 1
2 Marketing 7 7 Robert 3 0
2 Marketing 7 11 David 7 1
2 Marketing 7 12 Ron 7 1
2 Marketing 7 13 Dan 7 1
2 Marketing 7 14 James 11 2
3 Finance 8 8 Laura 3 0
4 R&D 9 9 Ann 3 0
5 Training 4 4 Margaret 1 0
5 Training 4 10 Ina 4 1
(12 row(s) affected)
-- outer apply
select *
from Departments as D
outer apply fn_getsubtree(D.deptmgrid) as ST
deptid deptname deptmgrid empid empname mgrid lvl
----------- ----------- ----------- ----------- ----------- ----------- ------
1 HR 2 2 Andrew 1 0
1 HR 2 5 Steven 2 1
1 HR 2 6 Michael 2 1
2 Marketing 7 7 Robert 3 0
2 Marketing 7 11 David 7 1
2 Marketing 7 12 Ron 7 1
2 Marketing 7 13 Dan 7 1
2 Marketing 7 14 James 11 2
3 Finance 8 8 Laura 3 0
4 R&D 9 9 Ann 3 0
5 Training 4 4 Margaret 1 0
5 Training 4 10 Ina 4 1
6 Gardening NULL NULL NULL NULL NULL
(13 row(s) affected)
注意 outer apply 结果集中多出的最后一行。 当 Departments 的最后一行在进行交叉联接时:deptmgrid 为 NULL,fn_getsubtree(D.deptmgrid) 生成的派生表中没有数据,但 outer apply 仍会包含这一行数据,这就是它和 cross join 的不同之处。
下面是完整的测试代码,你可以在 SQL Server 2005 联机帮助上找到:
-- create Employees table and insert values
create table Employees
(
empid int not null,
mgrid int NULL,
empname varchar(25) not null,
salary money not null
)
go
-- create Departments table and insert values
create table Departments
(
deptid int not null primary key,
deptname varchar(25) not null
)
go
-- fill datas
insert into employees values(1 , NULL, 'Nancy' , 000.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
-- table-value function
create function dbo.fn_getsubtree(@empid AS INT) returns @TREE table
(
empid int not null,
empname varchar(25) not null,
mgrid int null,
lvl int not null
)
as
begin
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
)
insert into @TREE
select * from Employees_Subtree
return
end
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
分享到:
相关推荐
SQL Server中的CROSS APPLY和OUTER APPLY是两种特殊的表运算符,它们在2005版本及以上引入,主要用于处理复杂的数据转换和联接操作。这些运算符的主要区别在于如何处理右表表达式的结果。 CROSS APPLY用于执行内联...
下面把sqlserver中cross apply和outer apply关键字具体介绍展示如下: 1.CROSS APPLY 和OUTER APPLY MSDN解释如下(个人理解不是很清晰): 使用 APPLY 运算符可以为实现查询操作的外部表表达式返回的每个行调用表值...
《SQL Server 2005 T-SQL增强》是一本专为SQL Server 2005用户准备的技术指南,深入探讨了T-SQL(Transact-SQL)在该版本中的新特性和强化功能。T-SQL是SQL Server的核心查询语言,用于数据查询、更新、插入和删除等...
在SQL Server 2005中,有了新的解决方案,我们可以利用`FOR XML PATH`结合`CROSS APPLY`或`OUTER APPLY`来达到相同的目的,但这种方法更加高效且直观。以下是一个例子: ```sql DECLARE @t TABLE(id int, value ...
SQL Server的APPLY表运算符是在SQL Server 2005及更高版本中引入的一个强大工具,它为复杂的查询提供了更多的灵活性。APPLY运算符分为两种类型:CROSS APPLY和OUTER APPLY,它们在处理数据时有显著的区别。 CROSS ...
本文由Itzik Ben-Gan和Solid Quality Learning发布,旨在介绍SQL Server 2005中的一些主要T-SQL新特性。以下是这些增强功能的详细说明: 1. **窗口函数(Window Functions)**:SQL Server 2005引入了窗口函数,如...
总的来说,`APPLY`运算符,特别是`CROSS APPLY`,在SQL Server 2008 R2中是一个强大的工具,可用于处理复杂的查询需求,如统计和聚合数据。结合窗口函数,它可以有效地解决特定的统计问题,如找出每个组的最新和次新...
在SQL Server 2008中,`APPLY`运算符是一种高级联接操作,它允许将一个查询的结果集作为另一个查询的输入,从而实现复杂的数据处理。`APPLY`运算符分为两种类型:`CROSS APPLY`和`OUTER APPLY`,它们都是在查询中...
窗口函数是SQL Server中非常强大的功能,它允许开发者在查询中进行更复杂的数据聚合操作。窗口函数特别适用于执行计算、排名和分组数据,其处理效率远高于传统的聚合函数。 28. OUTER APPLY、CROSS APPLY区别 OUTER...
- **CROSS APPLY和OUTER APPLY**:扩展了JOIN操作,允许在JOIN过程中调用用户定义的函数或子查询。 3. **安全性与权限管理** - **角色管理**:强化了角色管理,允许更精细的权限分配,例如服务器级别的角色和...
- 两个系统都支持`JOIN`操作,如`INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL JOIN`,但SQL Server的`CROSS APPLY`和`OUTER APPLY`提供了更灵活的连接方式,Oracle则没有直接对应的特性。 9. **游标**: - ...
7. **高级查询技巧**:使用PIVOT和UNPIVOT进行数据旋转,使用CROSS APPLY和OUTER APPLY进行复杂数据转换。 通过这两个CHM文件,学习者可以系统地了解和掌握SQL Server的基础知识和查询技能,结合实际代码讲解,将...
在SQL Server 2005中,`APPLY`运算符是一个重要的查询增强功能,它允许更灵活地在查询中使用表值函数。本篇学习笔记将深入探讨`APPLY`运算符的基本概念、用途以及与传统JOIN操作的对比。 `APPLY`运算符分为两种类型...
这个查询可以帮助我们了解 SQL Server 缓存中的执行计划,包括 SQL 语句文本、计划类型、数据库名称以及计划使用的次数等。 ##### 2. 最昂贵的查询 ```sql SELECT CAST(Total_elapsed_time / 1000000.0 AS DECIMAL...
2. **Transact-SQL增强**:SQL2005扩展了T-SQL语言,添加了窗口函数、CROSS APPLY和OUTER APPLY等新功能,使得复杂查询和数据分析更为便捷。 3. **企业管理器**:SQL Server Management Studio (SSMS) 是SQL2005的...
**行集函数**,如CROSS APPLY和OUTER APPLY,允许在查询中生成新的行集,通常与子查询或表值函数一起使用。 **安全函数**,与权限和角色管理相关,如IS_MEMBER()检查用户是否属于特定的角色。 **字符串函数**,如...