Medan M.Alis svar kommer att ge dig resultatet, eftersom du använder SQL Server 2012 skulle jag avpivotera name
och address
kolumner något annorlunda för att få det slutliga resultatet.
Eftersom du använder SQL Server 2012 kan du använda CROSS APPLY
med VALUES
för att avpivotera dessa flera kolumner till flera rader. Men innan du gör det skulle jag använda row_number()
för att få det totala antalet nya kolumner du kommer att ha.
Koden för att "UNPIVOT" data med hjälp av CROSS APPLY ser ut så här:
select d.loanid,
col = c.col + cast(seq as varchar(10)),
c.value
from
(
select loanid, name, address,
row_number() over(partition by loanid
order by loanid) seq
from yourtable
) d
cross apply
(
values
('name', name),
('address', address)
) c(col, value);
Se SQL Fiddle with Demo. Detta kommer att få dina data till ett format som liknar:
| LOANID | COL | VALUE |
|--------|----------|----------|
| 1 | name1 | John |
| 1 | address1 | New York |
| 1 | name2 | Carl |
| 1 | address2 | New York |
| 1 | name3 | Henry |
| 1 | address3 | Boston |
Du har nu en enda kolumn COL
med alla dina nya kolumnnamn och de associerade värdena finns också i en enda kolumn. De nya kolumnnamnen har nu ett nummer i slutet (1, 2, 3, etc) baserat på hur många totala poster du har per loanid
. Nu kan du använda PIVOT:
select loanid,
name1, address1, name2, address2,
name3, address3
from
(
select d.loanid,
col = c.col + cast(seq as varchar(10)),
c.value
from
(
select loanid, name, address,
row_number() over(partition by loanid
order by loanid) seq
from yourtable
) d
cross apply
(
values
('name', name),
('address', address)
) c(col, value)
) src
pivot
(
max(value)
for col in (name1, address1, name2, address2,
name3, address3)
) piv;
Se SQL Fiddle with Demo. Slutligen om du inte vet hur många par Name
och Address
du har då kan du använda dynamisk 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 loanid
order by loanid) seq
from yourtable
) d
cross apply
(
select 'Name', 1 union all
select 'Address', 2
) c (col, so)
group by seq, col, so
order by seq, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT loanid,' + @cols + '
from
(
select d.loanid,
col = c.col + cast(seq as varchar(10)),
c.value
from
(
select loanid, name, address,
row_number() over(partition by loanid
order by loanid) seq
from yourtable
) d
cross apply
(
values
(''name'', name),
(''address'', address)
) c(col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
exec sp_executesql @query;
Se SQL Fiddle with Demo. Båda versionerna ger ett resultat:
| LOANID | NAME1 | ADDRESS1 | NAME2 | ADDRESS2 | NAME3 | ADDRESS3 |
|--------|--------|----------|--------|----------|--------|----------|
| 1 | John | New York | Carl | New York | Henry | Boston |
| 2 | Robert | Chicago | (null) | (null) | (null) | (null) |
| 3 | Joanne | LA | Chris | LA | (null) | (null) |