博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQL Server 2008的cross apply 和 outer apply
阅读量:6303 次
发布时间:2019-06-22

本文共 4540 字,大约阅读时间需要 15 分钟。

我们知道有个 SQL Server 2000 中有个 cross join 是用于交叉联接的。实际上增加

cross apply 和 outer apply 是用于交叉联接表值函数(返回表结果集的函数)的,
更重要的是这个函数的参数是另一个表中的字段。这个解释可能有些含混不请,请看下面的例子:
-- 1. cross join
联接两个表
select*
 
from TABLE_1
as
T1
crossjoin TABLE_2 as T2
-- 2. cross join
联接表和表值函数,表值函数的参数是个“常量”
select*
 
from TABLE_1
T1
crossjoin FN_TableValue(100)
-- 3. cross join  联接表和表值函数,表值函数的参数是“表T1中的字段”
select*
 
from TABLE_1
T1
crossjoin FN_TableValue(T1.column_a)
Msg
4104, Level16, State 1,
Line
1
The multi
-part identifier
"T1.column_a" could
not be bound.
最后的这个查询的语法有错误。在
crossjoin 时,表值函数的参数不能是表 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
仍会包含这一行数据,这就是它和
crossjoin 的不同之处。
下面是完整的测试代码,你可以在 SQL Server
2005 联机帮助上找到:
-- create Employees
table and insert values
IFOBJECT_ID('Employees') ISNOTNULL
DROPTABLE
Employees
GO
CREATETABLE
Employees
(
empid
INTNOTNULL,
mgrid
INTNULL,
empname
VARCHAR(25) NOTNULL,
salary
MONEYNOTNULL
)
GO
IFOBJECT_ID('Departments') ISNOTNULL
DROPTABLE
Departments
GO
-- create Departments table and insert values
CREATETABLE
Departments
(
deptid
INTNOTNULLPRIMARYKEY,
deptname
VARCHAR(25) NOTNULL,
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
IFOBJECT_ID('fn_getsubtree') ISNOTNULL
DROPFUNCTION 
fn_getsubtree
GO
CREATE  FUNCTION
dbo.fn_getsubtree(
@empidASINT)
RETURNSTABLE
AS
RETURN(
 
WITH
Employees_Subtree(empid, empname, mgrid, lvl)
 
AS
  (
   
--
Anchor Member (AM)
    SELECT empid,
empname, mgrid,
0
   
FROM employees
   
WHERE
empid
=
@empid  
   
UNIONALL
   
-- 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

转载地址:http://lcfxa.baihongyu.com/

你可能感兴趣的文章
Oracle序列
查看>>
xcodebuild命令行编译错误问题解决
查看>>
Yii2.0 下的 load() 方法的使用
查看>>
华为畅玩5 (CUN-AL00) 刷入第三方twrp Recovery 及 root
查看>>
LeetCode----67. Add Binary(java)
查看>>
母版页 MasterPage
查看>>
[转] ReactNative Animated动画详解
查看>>
DNS原理及其解析过程
查看>>
记录自写AFNetWorking封装类
查看>>
没想到cnblog也有月经贴,其实C#值不值钱不重要。
查看>>
【转】LUA内存分析
查看>>
springboot使用schedule定时任务
查看>>
[转] Entity Framework Query Samples for PostgreSQL
查看>>
XDUOJ 1115
查看>>
PHP学习(四)---PHP与数据库MySql
查看>>
模版方法模式--实现的capp流程创建与管理
查看>>
软件需求分析的重要性
查看>>
eclipse的scala环境搭建
查看>>
UVA465:Overflow
查看>>
HTML5-placeholder属性
查看>>