Podczas gdy odpowiedź M.Ali da ci wynik, ponieważ używasz SQL Server 2012, odwróciłbym name
i address
kolumny nieco się różnią, aby uzyskać ostateczny wynik.
Ponieważ używasz SQL Server 2012, możesz użyć CROSS APPLY
z VALUES
aby przestawić te wiele kolumn na wiele wierszy. Ale zanim to zrobisz, użyję row_number()
aby uzyskać całkowitą liczbę nowych kolumn, które będziesz mieć.
Kod do „UNPIVOT” danych za pomocą CROSS APPLY wygląda następująco:
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);
Zobacz SQL Fiddle z wersją demonstracyjną. Spowoduje to uzyskanie danych w formacie podobnym do:
| LOANID | COL | VALUE |
|--------|----------|----------|
| 1 | name1 | John |
| 1 | address1 | New York |
| 1 | name2 | Carl |
| 1 | address2 | New York |
| 1 | name3 | Henry |
| 1 | address3 | Boston |
Masz teraz jedną kolumnę COL
wszystkie nowe nazwy kolumn i powiązane wartości również znajdują się w jednej kolumnie. Nowe nazwy kolumn mają teraz numer na końcu (1, 2, 3, itd.) w oparciu o liczbę wszystkich wpisów na loanid
. Teraz możesz zastosować 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;
Zobacz SQL Fiddle z demonstracją. Wreszcie, jeśli nie wiesz, ile par Name
i Address
będziesz miał wtedy możesz użyć dynamicznego 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;
Zobacz SQL Fiddle z demonstracją. Obie wersje dają wynik:
| 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) |