My table
CREATE TABLE #table
([Indicator] int, [Scenario_code] smallint, [period] nvarchar(50), [Value] int, [AREA code] nvarchar(10), [Release_Code] int)
The simplest way to get the result would be using an aggregate function with a CASE expression:
select
scenario_code,
max(case when indicator = 2 then period end) [Period 2],
max(case when indicator = 2 then value end) [Value 2],
max(case when indicator = 3 then period end) [Period 3],
max(case when indicator = 3 then value end) [Value 3],
max(case when indicator = 4 then period end) [Period 4],
max(case when indicator = 4 then value end) [Value 4],
[area code],
Release_Code
from yourtable
group by scenario_code, [area code], Release_Code
See SQL Fiddle with Demo
But you can use the PIVOT function to get the result but you would also need to unpivot the Period
and Value
columns first, since you want to pivot on two columns.
Since you are using SQL Server 2012 you can use CROSS APPLY with VALUES to unpivot. The basic syntax will be:
select scenario_code, [area code], release_code,
col = col +' ' +cast(indicator as varchar(10)),
val
from yourtable
cross apply
(
values
('Period', convert(varchar(10), period, 120)),
('Value', convert(varchar(10), value))
) c (col, val);
See SQL Fiddle with Demo. This is going to get your data into the format:
| SCENARIO_CODE | AREA CODE | RELEASE_CODE | COL | VAL |
|---------------|-----------|--------------|----------|------------|
| 7 | OP014 | 17 | Period 2 | 2000-06-13 |
| 7 | OP014 | 17 | Value 2 | 1000 |
| 16 | OP014 | 17 | Period 2 | 2000-09-12 |
| 16 | OP014 | 17 | Value 2 | 1100 |
You'll notice that we had to cast/convert both columns to the same datatype in order for this unpivoting process to work. Once the data has been unpivoted, then you can easily apply the PIVOT function and convert your values in COL
to the new column headers:
select scenario_code,
[Period 2], [Value 2],
[Period 3], [Value 3],
[Period 4], [Value 4],
[area code], release_code
from
(
select scenario_code, [area code], release_code,
col = col +' ' +cast(indicator as varchar(10)),
val
from yourtable
cross apply
(
values
('Period', convert(varchar(10), period, 120)),
('Value', convert(varchar(10), value))
) c (col, val)
) d
pivot
(
max(val)
for col in ([Period 2], [Value 2],
[Period 3], [Value 3],
[Period 4], [Value 4])
) piv;
See SQL Fiddle with Demo. Both versions give a final result of:
| SCENARIO_CODE | PERIOD 2 | VALUE 2 | PERIOD 3 | VALUE 3 | PERIOD 4 | VALUE 4 | AREA CODE | RELEASE_CODE |
|---------------|------------|---------|------------|---------|------------|---------|-----------|--------------|
| 7 | 2000-06-13 | 1000 | 2000-01-12 | 1300 | 2000-06-12 | 600 | OP014 | 17 |
| 16 | 2000-09-12 | 1100 | 2000-06-17 | 500 | 2000-12-12 | 650 | OP014 | 17 |
| 17 | 2002-06-22 | 1200 | 2008-05-04 | 550 | 2013-06-12 | 150 | OP014 | 17 |
try this,
;with CTE as
(select *,ROW_NUMBER()over(partition by Scenario_code order by period)rn from #table)
select distinct a.Scenario_code, b.period [period2],b.Value [Value2],c.period [period3],c.Value [Value3],d.period [period4],d.Value [Value4]
from CTE a left join CTE b on a.Scenario_code=b.Scenario_code and b.rn=1
left join CTE c on a.Scenario_code=c.Scenario_code and c.rn=2
left join CTE d on a.Scenario_code=d.Scenario_code and d.rn=3
drop table #table
Check Latest,then i didn't notice indicator
Select * from
(select ROW_NUMBER()over(partition by a.Scenario_code order by a.Scenario_code)rn , a.Scenario_code, b.period [period2],b.Value [Value2],c.period [period3],c.Value [Value3],d.period [period4],d.Value [Value4]
from #table a left join #table b on a.Scenario_code=b.Scenario_code and b.indicator=3
left join #table c on a.Scenario_code=c.Scenario_code and c.indicator=4
left join #table d on a.Scenario_code=d.Scenario_code and d.indicator=2
)t4 where rn=1