我有以下问题:我需要使用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做我打算做的事情)。无论如何,有人能指出我正确的方向我的问题吗?提前谢谢。
答案 0 :(得分:2)
是的,您可以使用PIVOT函数将数据行转换为列。您只需使用汇总函数max
或min
为每个日期选择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来获得结果:
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 |