如何在sql server列中显示行值?

时间:2016-05-18 08:29:53

标签: sql sql-server group-by union-all weekday

SQL FIDDLE DEMO HERE

我有SheduleWorkers表的这个表结构:

    CREATE TABLE SheduleWorkers
    (
         [Name] varchar(250),
         [IdWorker] varchar(250),    
         [IdDepartment] int,
         [IdDay] int,
         [Day] varchar(250)
    );


INSERT INTO SheduleWorkers ([Name],  [IdWorker],  [IdDepartment], [IdDay], [Day])
values 
('Sam', '001', 5, 1, 'Monday'),
('Lucas', '002', 5, 2, 'Tuesday'),
('Maria', '003', 5, 1, 'Monday'),
('José', '004', 5, 3, 'Wednesday'),
('Julianne', '005', 5, 3, 'Wednesday'),
('Elisa', '006', 18, 1, 'Monday'),
('Gabriel', '007', 23, 5, 'Friday');

我需要在每个工作日显示当天工作的部门5的工人姓名,如下所示:

MONDAY   TUESDAY   WEDNESDAY  THURSDAY  FRIDAY  SATURDAY
------   -------   ---------  --------  ------  -------
Sam       Lucas    Jose       
Maria              Julianne

我如何得到这个结果,我接受建议,谢谢。

3 个答案:

答案 0 :(得分:5)

DECLARE @SheduleWorkers TABLE
    (
      [Name] VARCHAR(250) ,
      [IdWorker] VARCHAR(250) ,
      [IdDepartment] INT ,
      [IdDay] INT ,
      [Day] VARCHAR(250)
    );


INSERT  INTO @SheduleWorkers
        ( [Name], [IdWorker], [IdDepartment], [IdDay], [Day] )
VALUES  ( 'Sam', '001', 5, 1, 'Monday' ),
        ( 'Lucas', '002', 5, 2, 'Tuesday' ),
        ( 'Maria', '003', 5, 1, 'Monday' ),
        ( 'José', '004', 5, 3, 'Wednesday' ),
        ( 'Julianne', '005', 5, 3, 'Wednesday' ),
        ( 'Elisa', '006', 18, 1, 'Monday' ),
        ( 'Gabriel', '007', 23, 5, 'Friday' );

;
WITH    cte
          AS ( SELECT   Name ,
                        Day ,
                        ROW_NUMBER() OVER ( PARTITION BY Day ORDER BY [IdWorker] ) AS rn
               FROM     @SheduleWorkers
             )
    SELECT  [MONDAY] ,
            [TUESDAY] ,
            [WEDNESDAY] ,
            [THURSDAY] ,
            [FRIDAY] ,
            [SATURDAY]
    FROM    cte PIVOT( MAX(Name) FOR day IN ( [MONDAY], [TUESDAY], [WEDNESDAY],
                                              [THURSDAY], [FRIDAY], [SATURDAY] ) ) p

输出:

MONDAY  TUESDAY WEDNESDAY   THURSDAY    FRIDAY  SATURDAY
Sam     Lucas   José        NULL        Gabriel NULL
Maria   NULL    Julianne    NULL        NULL    NULL
Elisa   NULL    NULL        NULL        NULL    NULL

主要思想是公共表表达式中的row_number窗口函数,它将为您提供与一天中最大重复项一样多的行。

答案 1 :(得分:2)

您可以使用pivot来实现此目的。请使用以下查询来解决您的问题。并使用分区。

SELECT  [Monday] , [Tuesday] , [Wednesday] , [Thursday] , [Friday], [SATURDAY]
FROM 
(SELECT [Day],[Name],RANK() OVER (PARTITION BY [Day] ORDER BY [Day],[Name]) as rnk
 FROM SheduleWorkers) p
 PIVOT(
Min([Name])
FOR [Day] IN
( [Monday] , [Tuesday] , [Wednesday] , [Thursday] , [Friday], [SATURDAY]  )
) AS pvt

答案 2 :(得分:1)

我建议您使用PIVOT和动态SQL来获取所需的所有日期名称:

DECLARE @column nvarchar(max),
        @sql nvarchar(max)

;WITH cte AS (
SELECT DATENAME(WEEKDAY,0) as [Day], 1 as [Level]
UNION ALL
SELECT DATENAME(WEEKDAY,[Level]), [Level] + 1
FROM cte
WHERE [Level] < 7
)

SELECT @column = STUFF((SELECT ','+QUOTENAME([Day]) FROM cte ORDER BY [Level]FOR XML PATH('')),1,1,'')

SELECT @sql = 
'SELECT '+@column+'
FROM (
    SELECT Name, [Day], RANK() OVER (PARTITION BY [Day] ORDER BY [Day],IdWorker) as rn
    FROM #SheduleWorkers
) as p
PIVOT
(
MAX(NAMe) FOR [Day] IN ('+@column+')
) as pvt'

EXEC(@sql)

输出:

Monday  Tuesday Wednesday   Thursday    Friday  Saturday    Sunday
Sam     Lucas   Jose        NULL        Gabriel NULL        NULL
Maria   NULL    Julianne    NULL        NULL    NULL        NULL
Elisa   NULL    NULL        NULL        NULL    NULL        NULL