想象一下,我们有以下数据集:
Name City Date
Paul Milan 04/01/2013
Charls Rome 04/01/2013
Jim Tokyo 04/01/2013
Justin San Francisco 04/01/2013
Bill London 04/01/2013
Paul Berlin 05/01/2013
Charls El Cairo 05/01/2013
Jim Milan 05/01/2013
Justin Paris 05/01/2013
Bill Madrid 05/01/2013
每个人[Name]
在某一天[City]
访问了某个城镇[Date]
。
我们要做的是建立一个包含[Name]
,[City day 1]
,[City day 2]
的表格,如下所示:
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
我们如何编写查询来执行此操作?
答案 0 :(得分:2)
此类数据转换称为PIVOT
。从SQL Server 2005开始,有一个函数可以为您执行此数据轮换。但这可以通过许多不同的方式完成。
您可以使用聚合函数和CASE
转移数据:
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
或者您可以使用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
这甚至可以通过多次加入你的桌子来完成:
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:
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)
他们都给出了结果:
| 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 |
答案 1 :(得分:1)
最简单的方法是使用CASE
SELECT Name,
MAX(CASE WHEN DATE = '04/01/2013' THEN City END) [City 04/01/2013],
MAX(CASE WHEN DATE = '05/01/2013' THEN City END) [City 05/01/2013]
FROM tableName
GROUP BY Name