为了得到结果,您需要将UNPIVOT和PIVOT功能同时应用于数据。 UNPIVOT将取得列(ID,网站)并将它们转换为行,一旦完成,您可以将数据转移回列。
的UNPIVOT代码将类似于以下内容:
select name,
col+'_'+cast(col_num as varchar(10)) col,
value
from
(
select name,
cast(id as varchar(11)) id,
website,
row_number() over(partition by name order by id) col_num
from yt
) src
unpivot
(
value
for col in (id, website)
) unpiv;
见SQL Fiddle with Demo。这给出了一个结果:
| NAME | COL | VALUE |
-------------------------------------
| Aaron | id_1 | 2305 |
| Aaron | website_1 | CoolSave1 |
| Aaron | id_2 | 8464 |
| Aaron | website_2 | DiscoWorld1 |
正如你可以看到我的逆转置施加row_number()
的数据之前,行号是用来生成新的列名。 UNPIVOT中的列也必须具有相同的数据类型,我在子查询中将cast
应用于id
列,以便在数据透视之前将数据转换为varchar
。
然后在PIVOT中使用col
值。一旦数据已经unpivot操作,在应用旋转功能:
select *
from
(
select name,
col+'_'+cast(col_num as varchar(10)) col,
value
from
(
select name,
cast(id as varchar(11)) id,
website,
row_number() over(partition by name order by id) col_num
from yt
) src
unpivot
(
value
for col in (id, website)
) unpiv
) d
pivot
(
max(value)
for col in (id_1, website_1, id_2, website_2, id_3, website_3)
) piv;
见SQL Fiddle with Demo。
上面的版本很有用,如果你有一个有限或已知数量的值。但是,如果行数是未知的,那么你就需要使用动态SQL生成结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(col+'_'+cast(col_num as varchar(10)))
from
(
select row_number() over(partition by name order by id) col_num
from yt
) t
cross apply
(
select 'id' col union all
select 'website'
) c
group by col, col_num
order by col_num, col
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT name,' + @cols + '
from
(
select name,
col+''_''+cast(col_num as varchar(10)) col,
value
from
(
select name,
cast(id as varchar(11)) id,
website,
row_number() over(partition by name order by id) col_num
from yt
) src
unpivot
(
value
for col in (id, website)
) unpiv
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute(@query);
见SQL Fiddle with Demo。两个版本都给出了结果:
| NAME | ID_1 | WEBSITE_1 | ID_2 | WEBSITE_2 | ID_3 | WEBSITE_3 |
------------------------------------------------------------------------
| Aaron | 2305 | CoolSave1 | 8464 | DiscoWorld1 | (null) | (null) |
| Adriana | 2956 | NewCin1 | 4563 | NewCin3 | 5991 | NewCin2 |
我喜欢带提琴手的演示。问题:这不是纯粹的SQL,但稍微像存储过程/程序吧? – 2013-04-10 17:14:16
@Menelaos第二个将在存储过程中运行。 – Taryn 2013-04-10 17:15:40