SQL2005学习笔记 APPLY 运算符
更新时间:2009年07月19日 01:49:49 作者:
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版本
declare @ids int
select @ids =0
declare @data nvarchar(200)
select @data=''
--定义表变量临时存放数据
declare @tem table(
ids int,
id int,
value nvarchar(100)
)
DECLARE test_cursor CURSOR FOR
SELECT ids, Data FROM MyData
OPEN test_cursor
FETCH NEXT FROM test_cursor
INTO @ids,@data
WHILE @@FETCH_STATUS = 0
begin
insert into @tem
select @ids,id,value
from dbo.fun_MyData(@data)
FETCH NEXT FROM test_cursor
INTO @ids,@data
end
CLOSE test_cursor
DEALLOCATE test_cursor
select * from @tem
同样得到了结果,但是sql2000要利用循环,这样代码复杂,计算耗时。
让我们充分利用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版本
declare @ids int
select @ids =0
declare @data nvarchar(200)
select @data=''
--定义表变量临时存放数据
declare @tem table(
ids int,
id int,
value nvarchar(100)
)
DECLARE test_cursor CURSOR FOR
SELECT ids, Data FROM MyData
OPEN test_cursor
FETCH NEXT FROM test_cursor
INTO @ids,@data
WHILE @@FETCH_STATUS = 0
begin
insert into @tem
select @ids,id,value
from dbo.fun_MyData(@data)
FETCH NEXT FROM test_cursor
INTO @ids,@data
end
CLOSE test_cursor
DEALLOCATE test_cursor
select * from @tem
同样得到了结果,但是sql2000要利用循环,这样代码复杂,计算耗时。
让我们充分利用Sql Server2005新兵器:APPLY运算符给我们带来的简便快捷的运算方式吧.
相关文章
Win2008中安装的MSSQL2005后无法访问的解决方法
最近笔者一直在使用Win2008系统,不过发现一个很奇怪的问题,那就是在该系统上安装了SQL2005后,再在其他计算机访问该主机显示不能访问2014-07-07SQLSERVER 2005中使用sql语句对xml文件和其数据的进行操作(很全面)
由于数据库对xml数据直接处理有很多优势,05也对这方面加强了功能。下面是一些实例代码,大家可以参考下。2010-06-06使用SQLSERVER 2005/2008 递归CTE查询树型结构的方法
我们经常遇到树型结构,把它们显示在一个类似TreeView控件上的情况。这时我们可以使用Recursive Common Table Expressions(CTE)实现2011-10-10让sql2005运行在独立用户下出现 WMI 提供程序错误的解决方式
您还有 %1 的时间注销,如果您 在此时间到之后仍没有注销,您的会话 将会断开,任何打开的文件或设备 就可能丢失数据2012-11-11sqlserver 存储过程中的top+变量使用分析(downmoon)
sqlserver 存储过程中的top+变量使用分析(downmoon) ,需要的朋友可以参考下。2011-05-05sqlserver2005 master与msdb数据库备份恢复过程
master与msdb数据库的备份与普通数据库一样,恢复master与msdb数据库关键在于以单用户模式启动,其它并没有太大的区别,下面详细说明使用方法2014-01-01
最新评论