これは、次のPIVOT
ような Split 関数も実装する場合に実行できます。
分割機能:
CREATE FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))
returns @temptable TABLE (items varchar(MAX))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end;
次に、列に変換する値がわかっている場合は、静的ピボットを使用して値をハードコーディングできます。
select *
from
(
select h.memberid,
h.cols,
r.results
from
(
select t1.resultid,
t1.testid,
t1.memberid,
h.items cols,
row_number() over(partition by memberid order by memberid) rn
from table1 t1
cross apply dbo.split(t1.headerdefinition, '|') h
where t1.testid = 1
) h
left join
(
select t1.resultid,
t1.testid,
t1.memberid,
r.items results,
row_number() over(partition by memberid order by memberid) rn
from table1 t1
cross apply dbo.split(t1.resultdefinition, '|') r
where t1.testid = 1
) r
on h.memberid = r.memberid
and h.rn = r.rn
) x
pivot
(
max(results)
for cols in ([Minutes Exercised], [KJ Burnt])
) p
デモで SQL Fiddle を参照してください
PIVOT
ただし、エントリごとに異なる数の列があるため、動的を使用する必要があると思います。コードは次のようになります。
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@testid int = 2
select @cols =
STUFF((SELECT ',' + QUOTENAME(x.cols)
from
(
select h.items cols,
row_number() over(partition by memberid order by memberid) rn
from table1 t1
cross apply dbo.split(t1.headerdefinition, '|') h
where t1.testid = @testid
) x
group by cols, rn
order by rn
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'SELECT memberid, ' + @cols + ' from
(
select h.memberid,
h.cols,
r.results
from
(
select t1.resultid,
t1.testid,
t1.memberid,
h.items cols,
row_number() over(partition by memberid order by memberid) rn
from table1 t1
cross apply dbo.split(t1.headerdefinition, ''|'') h
where t1.testid = '+ cast(@testid as varchar(10)) +'
) h
left join
(
select t1.resultid,
t1.testid,
t1.memberid,
r.items results,
row_number() over(partition by memberid order by memberid) rn
from table1 t1
cross apply dbo.split(t1.resultdefinition, ''|'') r
where t1.testid = '+ cast(@testid as varchar(10)) +'
) r
on h.memberid = r.memberid
and h.rn = r.rn
) x
pivot
(
max(results)
for cols in ('+@cols+')
) p'
execute(@query)
デモで SQL Fiddle を参照してください
次に、渡す結果に応じて、次の@testid
いずれかになります。
| MEMBERID | MINUTES EXERCISED | KJ BURNT |
-------------------------------------------
| 1 | 60 | 900 |
| 2 | 70 | 1000 |
または
| MEMBERID | HEIGHT | WEIGHT | BMI |
------------------------------------
| 1 | 142 | 94 | 35 |
| 3 | 150 | 60 | 20 |