这种类型的数据转换称为PIVOT
. 从 SQL Server 2005 开始,有一个函数可以为您执行此数据轮换。但这可以通过许多不同的方式来完成。
您可以使用聚合函数和 aCASE
来透视数据:
select
name,
max(case when date = '2013-04-01' then city end) [City 04/01/2013],
max(case when date = '2013-05-01' then city end) [City 05/01/2013]
from yourtable
group by name
请参阅带有演示的 SQL Fiddle
或者您可以使用以下PIVOT
功能:
select name, [2013-04-01] as [City 04/01/2013], [2013-05-01] as [City 05/01/2013]
from
(
select name, city, date
from yourtable
) src
pivot
(
max(city)
for date in ([2013-04-01], [2013-05-01])
) piv
请参阅SQL Fiddle with Demo。
这甚至可以通过多次加入您的桌子来完成:
select d1.name,
d1.city [City 04/01/2013],
d2.city [City 05/01/2013]
from yourtable d1
left join yourtable d2
on d1.name = d2.name
and d2.date = '2013-05-01'
where d1.date = '2013-04-01'
请参阅SQL Fiddle with Demo。
如果您知道要转换为列的日期,上述查询将非常有用。但是,如果您有未知数量的列,那么您将需要使用动态 sql:
DECLARE @cols AS NVARCHAR(MAX),
@colNames AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(char(10), date, 120))
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colNames = STUFF((SELECT distinct ',' + QUOTENAME(convert(char(10), date, 120)) +' as '+ QUOTENAME('City '+convert(char(10), date, 120))
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT name, ' + @colNames + ' from
(
select name,
city,
convert(char(10), date, 120) date
from yourtable
) x
pivot
(
max(city)
for date in (' + @cols + ')
) p '
execute(@query)
请参阅带有演示的 SQL Fiddle
他们都给出了结果:
| NAME | CITY 04/01/2013 | CITY 05/01/2013 |
----------------------------------------------
| Paul | Milan | Berlin |
| Charls | Rome | El Cairo |
| Jim | Tokyo | Milan |
| Justin | San Francisco | Paris |
| Bill | London | Madrid |