为了得到这个结果,你将不得不 UNPIVOT 然后 PIVOT 数据。UNPIVOT 将获取 、 、 和 列中的值fwildcardId
,refNumber
并将它们wildcardName
转换为行。一旦数据成行,您就可以应用 PIVOT 函数来获得最终结果。wildcardValue
comments
要取消透视数据,您可以使用 UNPIVOT 函数,也可以使用 CROSS APPLY 和 VALUES 子句。
取消透视:
select recordid,
col+cast(rn as varchar(10)) col,
unpiv_value
from
(
select recordid,
cast(fwildcardid as varchar(10)) fwildcardid,
cast(refnumber as varchar(10)) refnumber,
cast(wildcardname as varchar(10)) name,
cast(wildcardvalue as varchar(10)) value,
cast(comments as varchar(10)) comments,
row_number() over(partition by recordid
order by fwildcardid) rn
from tempp
) d
unpivot
(
unpiv_value
for col in (fwildcardid, refnumber, name, value, comments)
) c
请参阅SQL Fiddle with Demo。
交叉应用和价值观:
select recordid,
col+cast(rn as varchar(10)) col,
value
from
(
select recordid,
cast(fwildcardid as varchar(10)) fwildcardid,
cast(refnumber as varchar(10)) refnumber,
wildcardname,
wildcardvalue,
comments,
row_number() over(partition by recordid
order by fwildcardid) rn
from tempp
) d
cross apply
(
values
('fwildcardid', fwildcardid),
('refnumber', refnumber),
('name', wildcardname),
('value', wildcardvalue),
('comments', comments)
) c (col, value)
请参阅SQL Fiddle with Demo。
这些将结果转换为以下格式:
| RECORDID | COL | VALUE |
------------------------------------
| 404450 | fwildcardid1 | 154833 |
| 404450 | refnumber1 | 1 |
| 404450 | name1 | aa |
| 404450 | value1 | oi |
| 404450 | comments1 | p |
| 404450 | fwildcardid2 | 154834 |
当您将数据反透视到同一列时,它必须是相同的数据类型。您会注意到我将 a 应用于cast
列,因此数据类型是相同的。
数据为行格式后,您可以使用 PIVOT 将其转换回列:
select *
from
(
select recordid,
col+cast(rn as varchar(10)) col,
unpiv_value
from
(
select recordid,
cast(fwildcardid as varchar(10)) fwildcardid,
cast(refnumber as varchar(10)) refnumber,
cast(wildcardname as varchar(10)) name,
cast(wildcardvalue as varchar(10)) value,
cast(comments as varchar(10)) comments,
row_number() over(partition by recordid
order by fwildcardid) rn
from tempp
) d
unpivot
(
unpiv_value
for col in (fwildcardid, refnumber, name, value, comments)
) c
) src
pivot
(
max(unpiv_value)
for col in (fwildcardid1, refnumber1, name1, value1, comments1,
fwildcardid2, refnumber2, name2, value2, comments2)
) piv;
请参阅SQL Fiddle with Demo。
如果您有已知数量的列,则上述版本效果很好,但如果您有未知数量的值将被转换为列,那么您将需要使用动态 sql 来获取结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(c.col+cast(rn as varchar(10)))
from
(
select row_number() over(partition by recordid
order by fwildcardid) rn
from tempp
) t
cross apply
(
select 'fwildcardid' col, 1 sortorder union all
select 'refNumber', 2 union all
select 'name', 3 union all
select 'value', 4 union all
select 'comments', 5
) c
group by col, rn, sortorder
order by rn, sortorder
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT recordid,' + @cols + ' from
(
select recordid,
col+cast(rn as varchar(10)) col,
unpiv_value
from
(
select recordid,
cast(fwildcardid as varchar(10)) fwildcardid,
cast(refnumber as varchar(10)) refnumber,
cast(wildcardname as varchar(10)) name,
cast(wildcardvalue as varchar(10)) value,
cast(comments as varchar(10)) comments,
row_number() over(partition by recordid
order by fwildcardid) rn
from tempp
) d
unpivot
(
unpiv_value
for col in (fwildcardid, refnumber, name, value, comments)
) c
) src
pivot
(
max(unpiv_value)
for col in (' + @cols + ')
) p '
execute(@query);
请参阅SQL Fiddle with Demo。这两个都给出了结果:
| RECORDID | FWILDCARDID1 | REFNUMBER1 | NAME1 | VALUE1 | COMMENTS1 | FWILDCARDID2 | REFNUMBER2 | NAME2 | VALUE2 | COMMENTS2 |
-------------------------------------------------------------------------------------------------------------------------------
| 404450 | 154833 | 1 | aa | oi | p | 154834 | 2 | aaa | p | p |
| 406115 | 154867 | 1 | 98 | ff | ff | (null) | (null) | (null) | (null) | (null) |
| 406199 | 154869 | 1 | kki | aaaa | ssss | (null) | (null) | (null) | (null) | (null) |
| 406212 | 154880 | 1 | bbbbb | card | comm | (null) | (null) | (null) | (null) | (null) |