分别使用函数及游标实现SQL多行转一列(文本合并)
2013-11-22 23:04
253 查看
分别使用函数及游标实现SQL多行转一列
有时候在一些系统中我们需要用SQL语句将一对多关系表中的数据以每条记录一行的形式进行显示。本文分别采用函数及游标的方法来实现该功能。
示例表描述如下
一张用户表及文档表
现在想实现如下功能,查询出每个用户及其对应的文档名称的综合,如下结果
userID userName DocNames
1 fengyan sql基础,asp.net入门
2 eflylab 精品美食
注意到最后一列是类似统计。这就决定不能使用left join做,那样1号用户会出现二行,不是期望的
其实很多时间需求是需要我们使用SQL完成这样的功能,而不是放在程序里!如果做?
这里可以写一个函数来完成该功能
CREATE function f_getUserDocsByUserID(@userID int)
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str=''
select @str=@str+','+docName from Doc where UserID=@userID
if(len(@str)>1)
set @str=right(@str,len(@str)-1)
return(@str)
则相应的查询语句为
select u.*,study.dbo.f_getUserDocsByUserID(u.userID) as docs from [user] as u
运行效果
实现功能,这里仅以很简单的示例,演示了将多行转换成一列的需求,实际中针对docs的结果可能更复杂一些。
需要相应的变通!
第二种方式可以使用游标,这对于很多不理解和不会应用游标的朋友来说,可以学习一下!
--定义结果集表变量
DECLARE @t TABLE(userID varchar(10),userName varchar(100),DocNames varchar(8000))
--定义游标并进行合并处理
DECLARE MyCURSOR CURSOR
FOR
SELECT u.*,d.docName FROM [user] u left join [Doc] d on u.userID=d.userID order by u.userID
DECLARE @userID_old int,@userID int,@userName varchar(50),@oldUserName varchar(50),@docName varchar(50),@s varchar(100)
--打开游标
OPEN MyCURSOR
FETCH MyCURSOR INTO @userID,@userName,@docName
SELECT @userID_old=@userID,@s='',@oldUserName=@userName
WHILE @@FETCH_STATUS=0 --游标存在数据时循环
BEGIN
IF @userID=@userID_old --如果当前记录和上一条用户ID相同,则更改变量@s的值
SELECT @s=@s+','+@docName
ELSE
BEGIN --否则 已经是下一位用户了,应该执行添加操作
--UserID改变的时候添加操作
INSERT @t VALUES(@userID_old,@oldUserName,STUFF(@s,1,1,''))
--将新的文件名赋值给@s 并且更新@userID_old,@oldUserName
SELECT @s=','+@docName,@userID_old=@userID,@oldUserName=@userName
END
FETCH MyCURSOR INTO @userID,@userName,@docName
END
INSERT @t VALUES(@userID_old,@oldUserName,STUFF(@s,1,1,''))
CLOSE MyCURSOR
DEALLOCATE MyCURSOR
--显示结果
SELECT * FROM @t
运行结果如下:
也达到预期,在这里使用了一条left join查询
SELECT u.*,d.docName FROM [user] u left join [Doc] d on u.userID=d.userID order by u.userID
它的执行结果如下:
在方法二中使用游标在这个结果表中循环。中间使用一个变量结果表@t将结果存入@t中,最后@t即为所需结果
有时候在一些系统中我们需要用SQL语句将一对多关系表中的数据以每条记录一行的形式进行显示。本文分别采用函数及游标的方法来实现该功能。
示例表描述如下
一张用户表及文档表
现在想实现如下功能,查询出每个用户及其对应的文档名称的综合,如下结果
userID userName DocNames
1 fengyan sql基础,asp.net入门
2 eflylab 精品美食
注意到最后一列是类似统计。这就决定不能使用left join做,那样1号用户会出现二行,不是期望的
其实很多时间需求是需要我们使用SQL完成这样的功能,而不是放在程序里!如果做?
这里可以写一个函数来完成该功能
CREATE function f_getUserDocsByUserID(@userID int)
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str=''
select @str=@str+','+docName from Doc where UserID=@userID
if(len(@str)>1)
set @str=right(@str,len(@str)-1)
return(@str)
则相应的查询语句为
select u.*,study.dbo.f_getUserDocsByUserID(u.userID) as docs from [user] as u
运行效果
实现功能,这里仅以很简单的示例,演示了将多行转换成一列的需求,实际中针对docs的结果可能更复杂一些。
需要相应的变通!
第二种方式可以使用游标,这对于很多不理解和不会应用游标的朋友来说,可以学习一下!
--定义结果集表变量
DECLARE @t TABLE(userID varchar(10),userName varchar(100),DocNames varchar(8000))
--定义游标并进行合并处理
DECLARE MyCURSOR CURSOR
FOR
SELECT u.*,d.docName FROM [user] u left join [Doc] d on u.userID=d.userID order by u.userID
DECLARE @userID_old int,@userID int,@userName varchar(50),@oldUserName varchar(50),@docName varchar(50),@s varchar(100)
--打开游标
OPEN MyCURSOR
FETCH MyCURSOR INTO @userID,@userName,@docName
SELECT @userID_old=@userID,@s='',@oldUserName=@userName
WHILE @@FETCH_STATUS=0 --游标存在数据时循环
BEGIN
IF @userID=@userID_old --如果当前记录和上一条用户ID相同,则更改变量@s的值
SELECT @s=@s+','+@docName
ELSE
BEGIN --否则 已经是下一位用户了,应该执行添加操作
--UserID改变的时候添加操作
INSERT @t VALUES(@userID_old,@oldUserName,STUFF(@s,1,1,''))
--将新的文件名赋值给@s 并且更新@userID_old,@oldUserName
SELECT @s=','+@docName,@userID_old=@userID,@oldUserName=@userName
END
FETCH MyCURSOR INTO @userID,@userName,@docName
END
INSERT @t VALUES(@userID_old,@oldUserName,STUFF(@s,1,1,''))
CLOSE MyCURSOR
DEALLOCATE MyCURSOR
--显示结果
SELECT * FROM @t
运行结果如下:
也达到预期,在这里使用了一条left join查询
SELECT u.*,d.docName FROM [user] u left join [Doc] d on u.userID=d.userID order by u.userID
它的执行结果如下:
在方法二中使用游标在这个结果表中循环。中间使用一个变量结果表@t将结果存入@t中,最后@t即为所需结果
相关文章推荐
- 分别使用函数及游标实现SQL多行转一列
- 分别使用函数及游标实现SQL多行转一列
- 使用函数及游标实现SQL多行转一列
- sql多行转为一列的合并问题
- 使用SQL字符串反转函数REVERSE巧妙实现lastindexof功能
- Linux下使用xargs将多行文本转换成一行并用tr实现逗号隔开
- 简单实用SQL脚本Part:sql多行转为一列的合并问题
- 翻译:如何使用CSS实现多行文本的省略号显示
- 函数内巧用注释实现多行文本拼接
- 分别使用c、shell语言实现文件内容合并 -- 2014百度面试题目
- ORACLE纯SQL实现多行合并一行
- 一个Excel导入SQL server的例子(分别使用游标、CTE、master..spt_values实现)
- DB2 SQL 递归实现多行合并
- sparkSQL里 sql语句,dataframe,Thrift Server JDBC都可以实现对数据的查询,过滤等操作, 哪这3种情况分别是什么情况下使用
- 使用DBMS_SQL实现动态sql游标
- 利用Oracle分析函数实现多行数据合并为一行
- 利用 T-sql 的从句 for xml path('') 实现多行合并到一行, 并带有分隔符
- 简单实用SQL脚本Part:sql多行转为一列的合并问题
- 使用SQL字符串反转函数REVERSE巧妙实现lastindexof功能
- 使用pdfbox实现pdf文本提取和合并功能示例