在SQL Server 2005中的日历上使用PIVOT

时间:2013-08-22 15:58:44

标签: sql-server-2005 pivot

我有以下问题:我需要使用SQL Server 2005实现一个日历。这是我的存储过程到目前为止给我的一个例子:

TIME  |    DATE    |  CALENDAR_ID |  SUBJECT  |  NOTES  | STATUS_ID
===================================================================
09:00 | 19/08/2013 | 1            | SUBJECT 1 | NOTES 1 | 1
10:00 | 19/08/2013 | 2            | SUBJECT 2 | NOTES 2 | 2
11:00 | 19/08/2013 | 3            | SUBJECT 3 | NOTES 3 | 3
12:00 | 19/08/2013 | 4            | SUBJECT 4 | NOTES 4 | 1
09:00 | 20/08/2013 | 5            | SUBJECT 5 | NOTES 5 | 4
10:00 | 20/08/2013 | 6            | SUBJECT 6 | NOTES 6 | 3
11:00 | 20/08/2013 | 7            | SUBJECT 7 | NOTES 7 | 1
12:00 | 20/08/2013 | 8            | SUBJECT 8 | NOTES 8 | 1

但我想像这样显示:

TIME  | 19/08/2013 | 20/08/2013
===============================
09:00 | SUBJECT 1  | SUBJECT 5
10:00 | SUBJECT 2  | SUBJECT 6
11:00 | SUBJECT 3  | SUBJECT 7
12:00 | SUBJECT 4  | SUBJECT 8

我知道SQL Server中的PIVOT函数似乎对这些情况很有用,我搜索了示例和解释,但我仍然完全不理解。此外,到目前为止,我只看到了例如获得每月销售总额的例子;我不确定我的日历可以使用相同的逻辑(或者即使我可以使用PIVOT做我打算做的事情)。无论如何,有人能指出我正确的方向我的问题吗?提前谢谢。

1 个答案:

答案 0 :(得分:2)

是的,您可以使用PIVOT函数将数据行转换为列。您只需使用汇总函数maxmin为每个日期选择subject。如果您要将有限数量的日期转换为列,则可以对查询进行硬编码:

select [time], [19/08/2013], [20/08/2013]
from
(
  select [time], [date], subject
  from yourtable
) d
pivot
(
  max(subject)
  for [date] in ([19/08/2013], [20/08/2013])
) piv;

请参阅SQL Fiddle with Demo

但是如果你有一个未知数量的值,那么你可以在存储过程中使用动态SQL来获得结果:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(DATE) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT [time], ' + @cols + ' 
            from 
            (
              select [time], [date], subject
              from yourtable
            ) x
            pivot 
            (
                max(subject)
                for [date] in (' + @cols + ')
            ) p '

execute sp_executesql @query;

SQL Fiddle with Demo。两者都会给出结果:

|  TIME | 19/08/2013 | 20/08/2013 |
-----------------------------------
| 09:00 |  SUBJECT 1 |  SUBJECT 5 |
| 10:00 |  SUBJECT 2 |  SUBJECT 6 |
| 11:00 |  SUBJECT 3 |  SUBJECT 7 |
| 12:00 |  SUBJECT 4 |  SUBJECT 8 |