在将动态列转置为行的同时,连接列中的多个行

时间:2019-03-05 11:47:40

标签: sql-server

下面是我的表结构。

ScheduleDate    FirstName   ShiftName
3/1/2019        Emp2        SHIFT A 
3/2/2019        Emp2        SHIFT A 
3/2/2019        Emp3        SHIFT A 
3/2/2019        Emp1        SHIFT A 
3/1/2019        Emp3        SHIFT B 
3/2/2019        Emp2        SHIFT B 
3/2/2019        Emp3        SHIFT B 
3/2/2019        Emp1        SHIFT B 
3/1/2019        Emp1        SHIFT C 
3/2/2019        Emp2        SHIFT C 
3/2/2019        Emp3        SHIFT C 
3/2/2019        Emp1        SHIFT C 
3/1/2019        Emp4        WEEKLY OFF
3/2/2019        Emp4        WEEKLY OFF

我需要结果

FirstName   3/1/2019      3/2/2019
Emp1        SHIFT C       SHIFT A,SHIFT B ,SHIFT C 
Emp2        SHIFT A       SHIFT A,SHIFT B ,SHIFT C 
Emp3        SHIFT B       SHIFT A,SHIFT B ,SHIFT C 
Emp4        WEEKLY OFF    WEEKLY OFF

我需要将动态行转换为列,因为每个月的日期会有所不同。一名员工一天将有多个轮班。因此,如果需要,我需要在每天的多个班次上显示,并以逗号分隔。

这是我尝试过的内容,以下是我的SQL SERVER查询及其结果

 IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
    DROP TABLE #Temp

Select * Into 
    #Temp
    From 

(Select * from T_Test) as f
                        order by FirstName, ScheduleDate

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.ScheduleDate) 
            FROM  #Temp c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT FirstName, ' + @cols + ' from 
            (
                select FirstName
                    ,  ShiftNAme
                    , ScheduleDate
                from  #Temp 
           ) x
            pivot 
            (
                 max(ShiftName)
                for ScheduleDate in (' + @cols + ')
            ) p '

execute(@query)

结果是

FirstName   3/1/2019    3/2/2019
Emp1       SHIFT C      SHIFT C
Emp2       SHIFT A      SHIFT C 
Emp3       SHIFT B      SHIFT C
Emp4       WEEKLY OFF   WEEKLY OFF

但是我需要每天多班次才能与逗号连接。有人可以帮助我实现这一目标,谢谢您的帮助。

创建表的模式

CREATE TABLE [dbo].[T_Test](
    [ScheduleDate] [date] NOT NULL,
    [FirstName] [nvarchar](50) NOT NULL,
    [ShiftName] [nvarchar](50) NOT NULL
) ON [PRIMARY]

也插入查询

Insert into [dbo].[T_Test] (ScheduleDate,FirstName,ShiftName) values 
 ('2019-3-1','Emp2','SHIFT A'),
 ('2019-3-2','Emp2','SHIFT A'),
 ('2019-3-2','Emp3','SHIFT A'),
 ('2019-3-2','Emp1','SHIFT A'),
 ('2019-3-1','Emp3','SHIFT B'),
 ('2019-3-2','Emp2','SHIFT B'),
 ('2019-3-2','Emp3','SHIFT B'),
 ('2019-3-2','Emp1','SHIFT B'),
 ('2019-3-1','Emp1','SHIFT C'),
 ('2019-3-2','Emp3','SHIFT C'),
 ('2019-3-2','Emp1','SHIFT C'),
 ('2019-3-2','Emp2','SHIFT C'),
 ('2019-3-1','Emp4','WEEKLY OFF'),
 ('2019-3-2','Emp4','WEEKLY OFF')

注意:编辑1:我已经将其作为自由纯文本进行了编辑,并提供了表架构和查询,以便为您提供帮助。只需创建表,插入数据并执行我的查询即可。

1 个答案:

答案 0 :(得分:1)

好吧,我还是结束了。哇,这是一些可怕的/疯狂的SQL:

 DECLARE @SQL nvarchar(MAX);
 SET @SQL = N'SELECT T.FirstName,' + NCHAR(10) +
            STUFF((SELECT CONCAT(',',NCHAR(10),N'       STUFF((SELECT CONCAT('','',ShiftName)' + NCHAR(10) +
                                               N'              FROM T_Test S' + NCHAR(10) +
                                               N'              WHERE S.Firstname = T.FirstName' + NCHAR(10) +
                                               N'                AND S.ScheduleDate = ' + QUOTENAME(CONVERT(varchar(8),T.ScheduleDate,112),N'''')) + NCHAR(10) +
                                               N'              FOR XML PATH(N''''),TYPE).value(''.'',''varchar(MAX)''),1,1,N'''') AS ' + QUOTENAME(ScheduleDate)
                   FROM dbo.T_Test T
                   GROUP BY T.ScheduleDate
                   FOR XML PATH(N''),TYPE).value('.','varchar(MAX)'),1,2,N'') + NCHAR(10) +
            N'FROM T_Test T' + NCHAR(10) + 
            N'GROUP BY T.FirstName' + NCHAR(10) +
            N'ORDER BY T.FirstName;';

PRINT @SQL
EXEC sp_executesql @SQL;