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 

(转)https://blog.csdn.net/keenweiwei/article/details/41559257


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM