user2567873
user2567873

Reputation: 31

Populating data using a Pivot table

I have a table like this,

country 2007    2008    2009
 UK      5       10      20
 uk      5       10      20
 us     10       30      40
 us     10       30      40

But I want to populate the table like this,

country year    Total volumn
 uk     2007    10
 uk     2008    20
 uk     2009    40
 us     2007    20
 us     2008    60
 us     2009    80

How do I do this in SQL server 2008 using Pivot table or any other method.

http://sqlfiddle.com/#!3/2499a

Upvotes: 3

Views: 224

Answers (3)

Oleksandr Fedorenko
Oleksandr Fedorenko

Reputation: 16904

SELECT country, [year], SUM([Total volumn]) AS [Total volumn]
FROM (
      SELECT country, [2007], [2008], [2009]
      FROM dbo.test137
      ) p
UNPIVOT 
([Total volumn] FOR [year] IN ([2007], [2008], [2009])
) AS unpvt
GROUP BY country, [year]
ORDER BY country, [year]

See demo on SQLFiddle

Upvotes: 5

Taryn
Taryn

Reputation: 247720

Since you are using SQL Server 2008+, then you can use CROSS APPLY to unpivot the data from columns into rows.

You can use the VALUES clause with CROSS APPLY:

select distinct t.country,
  c.year,
  c.totalvolumn
from yourtable t
cross apply
(
  values 
  ('2007', 2007),
  ('2008', 2008),
  ('2009', 2009)
) c(year, TotalVolumn)
order by t.country, c.year;

See SQL Fiddle with Demo

Or you can use UNION ALL with CROSS APPLY:

select distinct t.country,
  c.year,
  c.totalvolumn
from yourtable t
cross apply
(
  select '2007', 2007 union all
  select '2008', 2008 union all
  select '2009', 2009 
) c(year, TotalVolumn)
order by t.country, c.year;

See SQL Fiddle with Demo.

This can also be written using a UNION query:

select country, '2007' year, 2007 totalVolumn
from yourtable 
union
select country, '2008' year, 2008 totalVolumn
from yourtable 
union
select country, '2009' year, 2009 totalVolumn
from yourtable 
order by country, year;

See SQL Fiddle with Demo

Upvotes: 2

Mez
Mez

Reputation: 4726

Try the following - and remember to change [DB] with your own database name. In my example you do not need to write the years, but they are extracted automatically for you.

-- will contain the temporary total
create table #tempResult (total int) 

-- get all countries
declare @countries table (country varchar(50))
insert into @countries
select country from table1

-- get all years
declare @years table(id int identity(1,1), [year] int)
insert into @years
SELECT column_name
FROM [DB].INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'Table1'
and column_name != 'country'

-- get all combinations
declare @result table(id int identity(1,1),country varchar(50),[year] int,total int)
insert into @result 
select distinct upper(c.country),y.[year],0
from @years as y,@countries as c

-- will be used for the looping
declare @counter int
select @counter = 1

while @counter <= (select count(*) from @result)
begin

declare @year int
declare @country varchar(50)

-- get year and country in question
select @year = [year] from @result where id = @counter
select @country = country from @result where id = @counter

declare @total int
select @total = (select sum(@year) from table1 where country = @country)

-- insert temp result 
declare @sql nvarchar(max)
set @sql = N'insert into #tempResult select sum([' + cast(@year as varchar(50)) + ']) from table1 where country = ''' + @country + ''''
print @sql

exec (@sql)

-- extract
select top 1 @total =  total from #tempResult

-- update respectively
update @result set total = @total
where country=@country and [year]=@year

-- clear
delete from #tempResult

select @counter = @counter + 1
end 

 -- select result
 select * From @result 

 drop table #tempResult

Upvotes: 2

Related Questions