UNPIVOT
結果を取得するために、関数と関数の両方を実装できPIVOT
ます。はUNPIVOT
列を取得してデータを行に変換し、ピボットは最終結果を取得して列に戻します。
select MemberID,
memberfirst,
memberlast,
isNull(GuestId_1, '') GuestId_1,
isNull(fname_1, '') fname_1,
isNull(lname_1, '') lname_1,
isNull(GuestId_2, '') GuestId_2,
isNull(fname_2, '') fname_2,
isNull(lname_2, '') lname_2
from
(
select MemberID,
memberfirst,
memberlast,
col+'_'+cast(rn as varchar(10)) col,
value
from
(
select m.MemberID,
m.fname MemberFirst,
m.lname MemberLast,
isNull(cast(g.GuestID as varchar(5)), '') GuestId,
isNull(g.fname, '') fname,
isNull(g.lname, '') lname,
row_number() over(partition by m.parentid order by g.guestid) rn
from member m
left join Event r
on m.parentid = r.memberid
left join guest g
on r.guestid = g.guestid
) src
unpivot
(
value
for col in (GuestId, fname, lname)
) unpiv
) src1
pivot
(
max(value)
for col in (GuestId_1, fname_1, lname_1,
GuestId_2, fname_2, lname_2)
) piv
SQL FiddlewithDemoを参照してください
上記は、レコードの数を事前に知っている場合はうまく機能しますが、そうでない場合は、動的SQLを使用することをお勧めします。
DECLARE @query AS NVARCHAR(MAX),
@colsPivot as NVARCHAR(MAX),
@colsPivotNull as NVARCHAR(MAX)
select @colsPivot = STUFF((SELECT ','
+ quotename(c.name +'_'+ cast(t.rn as varchar(10)))
from
(
select cast(row_number() over(partition by m.MemberID order by g.guestid) as varchar(50)) rn
from member m
left join Event r
on m.parentid = r.memberid
left join guest g
on r.guestid = g.guestid
) t
cross apply sys.columns as C
where C.object_id = object_id('guest')
group by c.name, t.rn
order by t.rn
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsPivotNull = STUFF((SELECT ', IsNull('
+ quotename(c.name +'_'+ cast(t.rn as varchar(10)))+', '''') as '+c.name +'_'+ cast(t.rn as varchar(10))
from
(
select cast(row_number() over(partition by m.MemberID order by g.guestid) as varchar(50)) rn
from member m
left join Event r
on m.parentid = r.memberid
left join guest g
on r.guestid = g.guestid
) t
cross apply sys.columns as C
where C.object_id = object_id('guest')
group by c.name, t.rn
order by t.rn
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'select
MemberID,
memberfirst,
memberlast, '+@colsPivotNull+'
from
(
select MemberID,
memberfirst,
memberlast,
col+''_''+cast(rn as varchar(10)) col,
value
from
(
select m.MemberID,
m.fname MemberFirst,
m.lname MemberLast,
isNull(cast(g.GuestID as varchar(5)), '''') GuestId,
isNull(g.fname, '''') fname,
isNull(g.lname, '''') lname,
row_number() over(partition by m.parentid order by g.guestid) rn
from member m
left join Event r
on m.parentid = r.memberid
left join guest g
on r.guestid = g.guestid
) x
unpivot
(
value
for col in (GuestId, fname, lname)
) u
) x1
pivot
(
max(value)
for col in ('+ @colspivot +')
) p'
exec(@query)
SQL FiddlewithDemoを参照してください
どちらのバージョンでも同じ結果が得られます。
| MemberID | MEMBERFIRST | MEMBERLAST | GUESTID_1 | FNAME_1 | LNAME_1 | GUESTID_2 | FNAME_2 | LNAME_2 |
-------------------------------------------------------------------------------------------------------
| 1 | Frank | Smith | 101 | Steve | Smith | 102 | Peter | Smith |
| 2 | Mary | Jane | 103 | Mike | Jane | | | |
| 3 | John | Henry | | | | | | |