将数据从行转换为列的过程称为 PIVOT。有几种方法可以做到这一点。
您可以将 arow_number()
与带有 CASE 表达式的聚合函数一起使用:
select min(id),
uid,
max(case when seq = 1 then name end) Name,
max(case when seq = 1 then code end) Code,
max(case when seq = 1 then Address1 end) Address1,
max(case when seq = 2 then name end) Name2,
max(case when seq = 2 then code end) code2,
max(case when seq = 2 then Address1 end) Address1_2
from
(
select id, uid, address1, name, code,
row_number() over(partition by uid order by id) seq
from yourtable
) d
group by uid;
请参阅SQL Fiddle with Demo。
您可以同时使用 UNPIVOT 和 PIVOT 函数:
select id, uid,
name1, code1, address1, name2, code2, address2
from
(
select id, uid, col+cast(seq as varchar(10)) col, value
from
(
select
(select min(id)
from yourtable t2
where t.uid = t2.uid) id,
uid,
cast(address1 as varchar(20)) address,
cast(name as varchar(20)) name,
cast(code as varchar(20)) code,
row_number() over(partition by uid order by id) seq
from yourtable t
) d
unpivot
(
value
for col in (address, name, code)
) unpiv
) src
pivot
(
max(value)
for col in (name1, code1, address1, name2, code2, address2)
) piv;
请参阅SQL Fiddle with Demo。
最后,如果每个 都有未知数量的值uid
,则可以使用动态 SQL 来获取结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(col+(cast(seq as varchar(10))))
from
(
select row_number() over(partition by uid order by id) seq
from yourtable
) d
cross apply
(
select 'name', 1 union all
select 'code', 2 union all
select 'address', 3
) c (col, so)
group by seq, col, so
order by seq, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT id, uid,' + @cols + '
from
(
select id, uid, col+cast(seq as varchar(10)) col, value
from
(
select
(select min(id)
from yourtable t2
where t.uid = t2.uid) id,
uid,
cast(address1 as varchar(20)) address,
cast(name as varchar(20)) name,
cast(code as varchar(20)) code,
row_number() over(partition by uid order by id) seq
from yourtable t
) d
unpivot
(
value
for col in (address, name, code)
) unpiv
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute(@query);
请参阅SQL Fiddle with Demo。所有版本都会给出一个结果:
| ID | UID | NAME1 | CODE1 | ADDRESS1 | NAME2 | CODE2 | ADDRESS2 |
---------------------------------------------------------------------
| 10 | 5 | Jac | 683501 | A | Joe | 727272 | B |
| 13 | 6 | mat | 373737 | C | (null) | (null) | (null) |