Sql Server2005 Transact-SQL 新兵器学习总结之-APPLY 运算符

SQL Server 2005 APPLY 运算符
介绍SQL Server 2005中新增的APPLY运算符使用方法,包括CROSS APPLY和OUTER APPLY的区别及应用示例,并对比SQL Server 2000的处理方式。

APPLY 运算符简介: 
APPLY 运算符是Sql Server2005新增加的运算符。

使用APPLY运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数。
表值函数作为右输入,外部表表达式作为左输入。
通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出。
APPLY运算符生成的列的列表是左输入中的列集,后跟右输入返回的列的列表。

APPLY 运算符的左操作数和右操作数都是表表达式。
这些操作数之间的主要区别是:右操作数可以使用表值函数,从左操作数获取一个列作为函数的参数之一。左操作数可以包括表值函数,但不能以来自右操作数的列作为参数。

演示一下APPLY 运算符的用法:

复制代码
--建一个表
CREATE TABLE MyData
(
  ids INT IDENTITY PRIMARY KEY,
  Data NVARCHAR(1000) 
)
go

--插入测试数据
INSERT INTO MyData VALUES('')
INSERT INTO MyData VALUES('a,b,c')
INSERT INTO MyData VALUES('q')
INSERT INTO MyData VALUES('i,p')
GO

select * from MyData
go
--查询结果
ids    Data
1    
2    a,b,c
3    q
4    i,p
复制代码

建立一个表,作用是:按逗号分解字符,分解出的每一个字符做一行数据返回

复制代码
create FUNCTION  fun_MyData(
@data AS NVARCHAR(1000)
)  
RETURNS @tem TABLE( id INT , value nvarchar(100) )
AS
BEGIN
    select @data=isnull(@data,'')

    if len(@data)=0
        return        --字符长度为0 ,退出

    declare @id AS INT
    select @id=1
    declare @end AS INT 

    select @end = CHARINDEX(',', @data)

    while(@end>0)
    begin
        insert into @tem(id,value)
        select @id,left(@data,@end-1)

        select @id=@id+1
        select @data=right(@data,len(@data)-@end)
        
        select @end = CHARINDEX(',', @data)
    end
    
    if len(@data)>0
    begin
        insert into @tem(id,value)
        select @id,@data
    end    
    
  RETURN
END


复制代码
开始使用APPLY 运算符:

复制代码
SELECT m.ids, f.*
FROM MyData m CROSS APPLY fun_MyData(data) f
go
--结果
ids    id    value
2    1    a
2    2    b
2    3    c
3    1    q
4    1    i
4    2    p

SELECT m.ids, f.* 
FROM MyData m OUTER APPLY fun_MyData(data) f
go
--结果
ids    id    value
1    NULL    NULL
2    1    a
2    2    b
2    3    c
3    1    q
4    1    i
4    2    p
复制代码

我们看到OUTER APPLY返回的结果行比CROSS APPLY多。
这一点有点象inner join(内部联接)和Left Outer Join(左外部联接)之间的关系.
其实APPLY有两种形式:CROSS APPLY 和 OUTER APPLY。
CROSS APPLY仅返回外部表中通过表值函数生成结果集的行。
OUTER APPLY既返回生成结果集的行,也返回不生成结果集的行,其中表值函数生成的列中的值为 NULL。


以上是sql2005的解决方案,下面我演示一下sql2000怎么解决这样的查询:
思路是:做个循环来逐个链接查询。

sql2000版本
同样得到了结果,但是sql2000要利用循环,这样代码复杂,计算耗时。
让我们充分利用Sql Server2005新兵器:APPLY运算符给我们带来的简便快捷的运算方式吧.

我的系列文章
A.Sql Server2005 Transact-SQL 新兵器学习 
B.MCAD学习 
C.代码阅读总结 
D.ASP.NET状态管理 
E.DB(数据库) 
F.WAP 
G.WinForm 
H.Flex

我的好文推荐
FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统((Flex,Fms3联合开发))<视频聊天,会议开发实例8> 
Sql Server2005 Transact-SQL 新兵器学习总结之-总结 
MS SQL数据库备份和恢复存储过程(加强版本) 
sql server中分布式查询随笔(链接服务器(sp_addlinkedserver)和远程登录映射(sp_addlinkedsrvlogin)使用小总结) 
ASP.NET2.0国际化/本地化应用程序的实现总结(多语言,多文化页面的实现) 
WAP开发资料站(最新更新) 
自定义格式字符串随笔 (IFormattable,IFormatProvider,ICustomFormatter三接口的实现) 
Mcad学习笔记之异步编程(AsyncCallback 委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结) 
Mcad学习笔记之通过反射调用類的方法,屬性,字段,索引器(2種方法) 
Mcad学习笔记之序列化(2进制和Soap序列 化) 
Mcad学习笔记之委托再理解(delegate的构造器,BeginInvoke,EndInvoke,Invoke4个方法的探讨) 
ASP.NET状态管理之一(概括篇) 
Flex,Fms学习笔记



APPLY 运算符简介: 
APPLY 运算符是Sql Server2005新增加的运算符。

使用APPLY运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数。
表值函数作为右输入,外部表表达式作为左输入。
通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出。
APPLY运算符生成的列的列表是左输入中的列集,后跟右输入返回的列的列表。

APPLY 运算符的左操作数和右操作数都是表表达式。
这些操作数之间的主要区别是:右操作数可以使用表值函数,从左操作数获取一个列作为函数的参数之一。左操作数可以包括表值函数,但不能以来自右操作数的列作为参数。

演示一下APPLY 运算符的用法:

复制代码
-- 建一个表
CREATE   TABLE  MyData
(
  ids 
INT   IDENTITY   PRIMARY   KEY ,
  Data 
NVARCHAR ( 1000
)
go

-- 插入测试数据
INSERT   INTO  MyData  VALUES ( '' )
INSERT   INTO  MyData  VALUES ( ' a,b,c ' )
INSERT   INTO  MyData  VALUES ( ' q ' )
INSERT   INTO  MyData  VALUES ( ' i,p ' )
GO

select   *   from  MyData
go
-- 查询结果
ids    Data
1     
2     a,b,c
3     q
4     i,p
复制代码


建立一个表,作用是:按逗号分解字符,分解出的每一个字符做一行数据返回

复制代码
create   FUNCTION   fun_MyData(
@data   AS   NVARCHAR ( 1000 )
)  
RETURNS   @tem   TABLE ( id  INT  , value  nvarchar ( 100 ) )
AS
BEGIN
    
select   @data = isnull ( @data , '' )

    
if   len ( @data ) = 0
        
return          -- 字符长度为0 ,退出

    
declare   @id   AS   INT
    
select   @id = 1
    
declare   @end   AS   INT  

    
select   @end   =   CHARINDEX ( ' , ' @data )

    
while ( @end > 0 )
    
begin
        
insert   into   @tem (id,value)
        
select   @id , left ( @data , @end - 1 )

        
select   @id = @id + 1
        
select   @data =right ( @data , len ( @data ) - @end )
        
        
select   @end   =   CHARINDEX ( ' , ' @data )
    
end
    
    
if   len ( @data ) > 0
    
begin
        
insert   into   @tem (id,value)
        
select   @id , @data
    
end     
    
  
RETURN
END


复制代码

开始使用APPLY 运算符:

复制代码
SELECT  m.ids, f. *
FROM  MyData m  CROSS  APPLY fun_MyData(data) f
go
-- 结果
ids    id    value
2      1     a
2      2     b
2      3     c
3      1     q
4      1     i
4      2     p

SELECT  m.ids, f. *  
FROM  MyData m  OUTER  APPLY fun_MyData(data) f
go
-- 结果
ids    id    value
1      NULL      NULL
2      1     a
2      2     b
2      3     c
3      1     q
4      1     i
4      2     p
复制代码


我们看到OUTER APPLY返回的结果行比CROSS APPLY多。
这一点有点象inner join(内部联接)和Left Outer Join(左外部联接)之间的关系.
其实APPLY有两种形式:CROSS APPLY 和 OUTER APPLY。
CROSS APPLY仅返回外部表中通过表值函数生成结果集的行。
OUTER APPLY既返回生成结果集的行,也返回不生成结果集的行,其中表值函数生成的列中的值为 NULL。


以上是sql2005的解决方案,下面我演示一下sql2000怎么解决这样的查询:
思路是:做个循环来逐个链接查询。

sql2000版本

同样得到了结果,但是sql2000要利用循环,这样代码复杂,计算耗时。
让我们充分利用Sql Server2005新兵器:APPLY运算符给我们带来的简便快捷的运算方式吧.

我的系列文章
A. Sql Server2005 Transact-SQL 新兵器学习  
B. MCAD学习 
C. 代码阅读总结 
D. ASP.NET状态管理 
E. DB(数据库) 
F. WAP 
G. WinForm 
H. Flex

我的好文推荐
FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统((Flex,Fms3联合开发))<视频聊天,会议开发实例8> 
Sql Server2005 Transact-SQL 新兵器学习总结之-总结 
MS SQL数据库备份和恢复存储过程(加强版本) 
sql server中分布式查询随笔(链接服务器(sp_addlinkedserver)和远程登录映射(sp_addlinkedsrvlogin)使用小总结) 
ASP.NET2.0国际化/本地化应用程序的实现总结(多语言,多文化页面的实现) 
WAP开发资料站(最新更新) 
自定义格式字符串随笔 (IFormattable,IFormatProvider,ICustomFormatter三接口的实现) 
Mcad学习笔记之异步编程(AsyncCallback 委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结) 
Mcad学习笔记之通过反射调用類的方法,屬性,字段,索引器(2種方法) 
Mcad学习笔记之序列化(2进制和Soap序列 化) 
Mcad学习笔记之委托再理解(delegate的构造器,BeginInvoke,EndInvoke,Invoke4个方法的探讨) 
ASP.NET状态管理之一(概括篇) 
Flex,Fms学习笔记


本文转自aierong博客园博客,原文链接http://www.cnblogs.com/aierong/archive/2008/08/13/1266937.html,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值