牛骨文教育服务平台(让学习变的简单)
博文笔记

SQL 多行拼成一行 (3种解决方案)

创建时间:2014-11-27 投稿人: 浏览次数:27063

SQL 多行拼成一行 (3种解决方案)

运行环境 (sql 2000, 2005, 2008, 2014 ), 其中,最后一种方法 专为sql 2000提供。


原数据:

(5 行受影响)
UserID      RoleName          RoleID
----------- ----------       --------
2014000     developer           1
2014000     product             2
2014001     developer           1
2014002     developer           1
2014002     sales               3

期望结果:

UserID      NewRoleName                NewRoleID
----------- ------------------        ------------ 
2014000     developer, product          1|2
2014001     developer                   1
2014002     developer, sales            1|3

解决方案:

原始数据脚本

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N"[dbo].[TEST]") AND type in (N"U"))
DROP TABLE [dbo].[TEST]
GO

create TABLE TEST(UserID INT,RoleName VARCHAR(100),RoleID INT)
INSERT INTO TEST
SELECT 2014000,"developer",1
UNION ALL SELECT 2014000,"product",2
UNION ALL SELECT 2014001,"developer",1
UNION ALL SELECT 2014002,"developer",1
UNION ALL SELECT 2014002,"sales",3

-- SELECT * FROM TEST 
-- SELECT * FROM TEST pivot( min(ROLEID) for USERID IN([2014000],[2014001],[2014002])) A

解决方法1:

SELECT t.UserID
	,STUFF((SELECT ","+ltrim(RoleName)
                    FROM TEST  
                    WHERE UserID=t.UserID FOR XML PATH("")), 1, 1, "") 
	AS NewRoleName
	,STUFF((SELECT "|"+ltrim(RoleID)
                    FROM TEST  
                    WHERE UserID=t.UserID FOR XML PATH("")), 1, 1, "") 
	AS NewRoleID
FROM TEST t
GROUP BY UserID

解决方法2:

SELECT A.*
	,STUFF(CONVERT(VARCHAR(100),C.RoleID),1,1,"") AS NewRoleID
	,REPLACE(
		STUFF(CONVERT(VARCHAR(100),C.RoleName),1,1,"")
		,"|",", ") AS NewRoleName
FROM (
	 SELECT DISTINCT UserID
		-- ,COUNT(DISTINCT ID) AS CountOfID
	 FROM TEST
	 GROUP BY UserID
) A
CROSS APPLY (
	 SELECT RoleID = (
		SELECT "|" + Convert(varchar(10),RoleID)
		FROM TEST B
		WHERE B.UserID = A.UserID
		FOR XML PATH(""), TYPE
	   ),
		RoleName = (
		SELECT "|" + Convert(varchar(10),RoleName)
		FROM TEST B
		WHERE B.UserID = A.UserID
		FOR XML PATH(""), TYPE
	   )
) C
 

解决方法3:

if object_id("F_RoleName") is not null 
    drop function F_RoleName 
go 
create function F_RoleName(@UserID VARCHAR(100)) 
returns nvarchar(100) 
as 
begin 
    declare @S nvarchar(100) 
    select @S=isnull(@S+", ","")+ RoleName from TEST where UserID=@UserID 
    return @S 
end 
go 


if object_id("F_RoleID") is not null 
    drop function F_RoleID 
go 
create function F_RoleID(@UserID VARCHAR(100)) 
returns nvarchar(100) 
as 
begin 
    declare @S nvarchar(100) 
    select @S=isnull(@S+"|","")+ ltrim(RoleID) from TEST where UserID=@UserID 
    return @S 
end 
go 

Select distinct UserID
	,NewRoleName=dbo.F_RoleName(UserID) 
	,NewRoleID=dbo.F_RoleID(UserID) 
from TEST 


声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。