爲了你得到的結果,我的建議是使用row_number()
窗函數,UNPIVOT你列statcode
, value_1
,value_2
和remarks
,最後應用PIVOT功能。
第一步是查詢您的數據並應用row_number()
函數。由於您有在列要多行數據,您需要一種方法來保持相互關聯的值:
select date, value_1, value_2, statcode, remarks,
row_number() over(partition by date
order by statcode) seq
from yourtable;
見Demo。這將爲表格中的每個日期的每行分配一個連續編號。我使用order by statcode
,但如果您有另一個值來保持項目的特定順序,那麼您將使用該列。
一旦您指定的行數,那麼你將在列statcode
,value_1
,value_2
和remarks
unpivot的數據。您可以使用UNPIVOT函數,也可以使用CROSS APPLY將多列轉換爲多行數據。當你改變你將留下3列,日期,上一列的值,然後將在PIVOT使用新列名的數據:
select date,
col = col+'_'+cast(seq as varchar(10)),
value
from
(
select date, value_1, value_2, statcode, remarks,
row_number() over(partition by date
order by statcode) seq
from yourtable
) src
cross apply
(
select 'statcode', statcode union all
select 'value_1', cast(value_1 as varchar(10)) union all
select 'value_2', cast(value_2 as varchar(10)) union all
select 'remarks', remarks
) c (col, value);
見Demo。這會給你的數據格式:
| DATE | COL | VALUE |
---------------------------------------------------------
| November, 01 2012 00:00:00+0000 | statcode_1 | SRC_1 |
| November, 01 2012 00:00:00+0000 | value_1_1 | 18775 |
| November, 01 2012 00:00:00+0000 | value_2_1 | 648 |
| November, 01 2012 00:00:00+0000 | remarks_1 | Normal |
| November, 01 2012 00:00:00+0000 | statcode_2 | SRC_2 |
| November, 01 2012 00:00:00+0000 | value_1_2 | 308218 |
最後將應用旋轉功能的項目在新的專欄中,我叫col
:
select date,
statcode_1, value_1_1, value_2_1, remarks_1,
statcode_2, value_1_2, value_2_2, remarks_2,
statcode_3, value_1_3, value_2_3, remarks_3
from
(
select date,
col = col+'_'+cast(seq as varchar(10)),
value
from
(
select date, value_1, value_2, statcode, remarks,
row_number() over(partition by date
order by statcode) seq
from yourtable
) src
cross apply
(
select 'statcode', statcode union all
select 'value_1', cast(value_1 as varchar(10)) union all
select 'value_2', cast(value_2 as varchar(10)) union all
select 'remarks', remarks
) c (col, value)
) d
pivot
(
max(value)
for col in (statcode_1, value_1_1, value_2_1, remarks_1,
statcode_2, value_1_2, value_2_2, remarks_2,
statcode_3, value_1_3, value_2_3, remarks_3)
) piv;
見SQL Fiddle with Demo。現在上面的代碼會爲你工作,你有一個已知的值,但如果你有未知的值,那麼你將需要使用動態SQL。動態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 date
order by statcode) seq
from yourtable
) t
cross apply
(
select 'statcode', 1 union all
select 'value_1', 2 union all
select 'value_2', 3 union all
select 'remarks', 4
) c (col, so)
group by col, seq, so
order by seq, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT date,' + @cols + '
from
(
select date,
col = col+''_''+cast(seq as varchar(10)),
value
from
(
select date, value_1, value_2, statcode, remarks,
row_number() over(partition by date
order by statcode) seq
from yourtable
) src
cross apply
(
select ''statcode'', statcode union all
select ''value_1'', cast(value_1 as varchar(10)) union all
select ''value_2'', cast(value_2 as varchar(10)) union all
select ''remarks'', remarks
) c (col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
見SQL Fiddle with Demo。兩種版本都會給出結果:
| DATE | STATCODE_1 | VALUE_1_1 | VALUE_2_1 | REMARKS_1 | STATCODE_2 | VALUE_1_2 | VALUE_2_2 | REMARKS_2 | STATCODE_3 | VALUE_1_3 | VALUE_2_3 | REMARKS_3 |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| November, 01 2012 00:00:00+0000 | SRC_1 | 18775 | 648 | Normal | SRC_2 | 308218 | 249 | Normal | SRC_3 | 0 | 0 | Off |
| November, 02 2012 00:00:00+0000 | SRC_4 | 123181 | 523 | Normal | SRC_5 | 189231 | 247 | Normal | (null) | (null) | (null) | (null) |
歡迎使用堆棧溢出。即使你嘗試過的東西不起作用,我們也很欣賞看到這些代碼。這證明你已經做了一個嘗試,並阻止你獲得你已經嘗試過的答案。 –
SRC_3行發生了什麼? –
@AaronBertrand我刪除了那一行。 – tanner