的solution that you link to將努力爲您的情況,但你有,因爲你想在轉動數據的多個列小幅調整。由於您需要對多個列進行透視,因此您首先需要將您的Visit Date
,Task
,Rf Score
和Pf Score
列轉化爲多行,然後應用透視函數。除了不透明的過程之外,我還建議使用,如row_number
來爲每個id
生成一個唯一的序列和日期。
您將使用以下開始查詢:
select id, task, [visit date], [rf score], [pf score],
row_number() over(partition by id
order by [visit date]) seq
from yourtable
見SQL Fiddle with Demo。這將創建一個數字,用於將Visit Date
,Task
,Rf Score
和Pf Score
中的每個值與實際訪問次數關聯起來。
一旦你有這個行號,那麼你會希望將你的多列轉化爲多行數據。有幾種方法可以做到這一點,包括使用unpivot功能。但因爲你正在使用SQL Server 2008 R2,您可以使用CROSS APPLY
與VALUES
:
select id,
col = col + cast(seq as varchar(10)),
value
from
(
select id, task, [visit date], [rf score], [pf score],
row_number() over(partition by id
order by [visit date]) seq
from yourtable
) d
cross apply
(
values
('VisitDate', convert(varchar(10), [visit date], 120)),
('Task', [task]),
('RfScore', cast([rf score] as varchar(10))),
('PfScore', cast([pf score] as varchar(10)))
) c (col, value)
見SQL Fiddle with Demo。你現在的數據是可以很容易地擺動的格式:
| ID | COL | VALUE |
|-------|------------|-----------------|
| 5180 | VisitDate1 | 2011-06-09 |
| 5180 | Task1 | Initial Visit |
| 5180 | RfScore1 | 3 |
| 5180 | PfScore1 | 9 |
| 5180 | VisitDate2 | 2011-07-08 |
| 5180 | Task2 | Follow Up Visit |
| 5180 | RfScore2 | 3 |
| 5180 | PfScore2 | 10 |
的代碼當添加PIVOT將非常具有:
select id,
VisitDate1, Task1, RfScore1, PfScore1,
VisitDate2, Task2, RfScore2, PfScore2,
VisitDate3, Task3, RfScore3, PfScore3,
VisitDate4, Task4, RfScore4, PfScore4,
VisitDate5, Task5, RfScore5, PfScore5,
VisitDate6, Task6, RfScore6, PfScore6
from
(
select id,
col = col + cast(seq as varchar(10)),
value
from
(
select id, task, [visit date], [rf score], [pf score],
row_number() over(partition by id
order by [visit date]) seq
from yourtable
) d
cross apply
(
values
('VisitDate', convert(varchar(10), [visit date], 120)),
('Task', [task]),
('RfScore', cast([rf score] as varchar(10))),
('PfScore', cast([pf score] as varchar(10)))
) c (col, value)
) d
pivot
(
max(value)
for col in (VisitDate1, Task1, RfScore1, PfScore1,
VisitDate2, Task2, RfScore2, PfScore2,
VisitDate3, Task3, RfScore3, PfScore3,
VisitDate4, Task4, RfScore4, PfScore4,
VisitDate5, Task5, RfScore5, PfScore5,
VisitDate6, Task6, RfScore6, PfScore6)
) piv;
見SQL Fiddle with Demo。
上述工程巨大的,如果你有一些有價值的數量有限,但如果是未知的,那麼你就需要使用動態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 id
order by [visit date]) seq
from yourtable
) d
cross apply
(
select 'VisitDate', 1 union all
select 'Task', 2 union all
select 'RfScore', 3 union all
select 'PfScore', 4
) c (col, so)
group by seq, col, so
order by seq, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'select id, ' + @cols + '
from
(
select id,
col = col + cast(seq as varchar(10)),
value
from
(
select id, task, [visit date], [rf score], [pf score],
row_number() over(partition by id
order by [visit date]) seq
from yourtable
) d
cross apply
(
values
(''VisitDate'', convert(varchar(10), [visit date], 120)),
(''Task'', task),
(''RfScore'', cast([rf score] as varchar(10))),
(''PfScore'', cast([pf score] as varchar(10)))
) c (col, value)
) s
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
見SQL Fiddle with Demo。兩個版本都給出了結果:
| ID | VISITDATE1 | TASK1 | RFSCORE1 | PFSCORE1 | VISITDATE2 | TASK2 | RFSCORE2 | PFSCORE2 | VISITDATE3 | TASK3 | RFSCORE3 | PFSCORE3 | VISITDATE4 | TASK4 | RFSCORE4 | PFSCORE4 | VISITDATE5 | TASK5 | RFSCORE5 | PFSCORE5 | VISITDATE6 | TASK6 | RFSCORE6 | PFSCORE6 | VISITDATE7 | TASK7 | RFSCORE7 | PFSCORE7 | VISITDATE8 | TASK8 | RFSCORE8 | PFSCORE8 |
|-------|------------|-----------------|----------|----------|------------|-----------------|----------|----------|------------|-----------------|----------|----------|------------|-----------------|----------|----------|------------|-----------------|----------|----------|------------|-----------------|----------|----------|------------|-----------------|----------|----------|------------|-----------------|----------|----------|
| 5180 | 2011-06-09 | Initial Visit | 3 | 9 | 2011-07-08 | Follow Up Visit | 3 | 10 | 2011-09-02 | Follow Up Visit | 1 | 10 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
| 5199 | 2011-09-08 | Follow Up Visit | 5 | 6 | 2011-09-15 | Follow Up Visit | 2 | 7 | 2011-10-13 | Follow Up Visit | 4 | 8 | 2011-10-20 | Follow Up Visit | 2 | 4 | 2011-10-27 | Follow Up Visit | 4 | 7 | 2011-11-03 | Follow Up Visit | 3 | 3 | 2011-11-10 | Follow Up Visit | 2 | 5 | 2011-11-17 | Follow Up Visit | 3 | 4 |
| 10219 | 2013-12-26 | Follow Up Visit | 1 | 6 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
你想讓最終結果看起來像什麼? – Taryn
我編輯了OP來包含這個細節。 – Baub
爲什麼你需要在SQL中執行這種類型的PIVOT?你能不能把結果返回給你的客戶,按照ID,Date排序,並保持水平直到你點擊一個新的ID? –