您可以使用 PIVOT 函数来获得结果,但您需要先使用其他一些函数才能获得最终产品。
首先,您需要为每一行创建一个唯一的序列(看起来好像没有),该值将用于创建新列的最终列表。您可以使用row_number() 创建此值:
select name, dob, location, phone,
row_number() over(order by name) seq
from yourtable
见SQL Fiddle with Demo。创建此唯一值后,您可以取消透视多列数据 name、dob、location 和 phone。根据您的 SQL Server 版本,您可以使用 unpivot 函数或 CROSS APPLY:
select 'N'+cast(seq as varchar(10)) seq,
category, value, so
from
(
select name, dob, location, phone,
row_number() over(order by name) seq
from yourtable
) src
cross apply
(
select 'name', name, 1 union all
select 'DOB', convert(varchar(10), dob, 120), 2 union all
select 'Location', location, 3 union all
select 'Phone', cast(phone as varchar(15)), 4
) c (category, value, so);
见SQL Fiddle with Demo。这将以以下格式获取您的数据:
| SEQ | CATEGORY | VALUE | SO |
|-----|----------|------------|----|
| N1 | name | Name1 | 1 |
| N1 | DOB | 2000-01-01 | 2 |
| N1 | Location | USA | 3 |
| N1 | Phone | 1234567890 | 4 |
现在您可以轻松应用 PIVOT 功能:
SELECT category, n1, n2
FROM
(
select 'N'+cast(seq as varchar(10)) seq,
category, value, so
from
(
select name, dob, location, phone,
row_number() over(order by name) seq
from yourtable
) src
cross apply
(
select 'name', name, 1 union all
select 'DOB', convert(varchar(10), dob, 120), 2 union all
select 'Location', location, 3 union all
select 'Phone', cast(phone as varchar(15)), 4
) c (category, value, so)
) d
pivot
(
max(value)
for seq in (N1, N2)
) piv
order by so;
见SQL Fiddle with Demo。如果您的值数量有限,上述方法非常有用,但如果您的 names 数量未知,那么您将需要使用动态 SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME('N'+cast(seq as varchar(10)))
from
(
select row_number() over(order by name) seq
from yourtable
)d
group by seq
order by seq
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT category, ' + @cols + '
from
(
select ''N''+cast(seq as varchar(10)) seq,
category, value, so
from
(
select name, dob, location, phone,
row_number() over(order by name) seq
from yourtable
) src
cross apply
(
select ''name'', name, 1 union all
select ''DOB'', convert(varchar(10), dob, 120), 2 union all
select ''Location'', location, 3 union all
select ''Phone'', cast(phone as varchar(15)), 4
) c (category, value, so)
) x
pivot
(
max(value)
for seq in (' + @cols + ')
) p
order by so'
execute sp_executesql @query;
见SQL Fiddle with Demo。他们都给出了以下结果:
| CATEGORY | N1 | N2 |
|----------|------------|------------|
| name | Name1 | Name2 |
| DOB | 2000-01-01 | 2000-01-02 |
| Location | USA | CAN |
| Phone | 1234567890 | 987654321 |