Trong khi câu trả lời của M.Ali sẽ cho bạn kết quả, vì bạn đang sử dụng SQL Server 2012, tôi sẽ bỏ chia nhỏ name
và address
các cột hơi khác nhau để có kết quả cuối cùng.
Vì bạn đang sử dụng SQL Server 2012, bạn có thể sử dụng CROSS APPLY
với VALUES
để bỏ chia nhiều cột này thành nhiều hàng. Nhưng trước khi bạn làm điều đó, tôi sẽ sử dụng row_number()
để nhận tổng số cột mới mà bạn sẽ có.
Mã để "UNPIVOT" dữ liệu bằng ÁP DỤNG CROSS trông giống như sau:
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);
Xem SQL Fiddle với Demo. Điều này sẽ đưa dữ liệu của bạn sang định dạng tương tự như:
| LOANID | COL | VALUE |
|--------|----------|----------|
| 1 | name1 | John |
| 1 | address1 | New York |
| 1 | name2 | Carl |
| 1 | address2 | New York |
| 1 | name3 | Henry |
| 1 | address3 | Boston |
Bây giờ bạn có một cột duy nhất COL
với tất cả các tên cột mới của bạn và các giá trị được liên kết cũng nằm trong một cột duy nhất. Tên cột mới hiện có một số ở cuối (1, 2, 3, v.v.) dựa trên tổng số mục nhập bạn có trên mỗi loanid
. Bây giờ bạn có thể áp dụng 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;
Xem SQL Fiddle với Demo. Cuối cùng nếu bạn không biết có bao nhiêu cặp Name
và Address
bạn sẽ có sau đó bạn có thể sử dụng SQL động:
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;
Xem SQL Fiddle với Demo. Cả hai phiên bản đều cho kết quả:
| 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) |