4

Possible Duplicate:
SQL Server dynamic PIVOT query?

Is it possible to execute a query on the following table:

Game    Player  Goals
-----   ------  ------
Game1   John    1
Game1   Paul    0
Game1   Mark    2
Game1   Luke    1
Game2   John    3
Game2   Paul    1   
Game2   Luke    1
Game3   John    0
Game3   Mark    2

which gives a result like this:

Game    John    Paul    Mark    Luke
-----   ----    ----    ----    ----
Game1   1       0       2       1
Game2   3       1       -       1
Game3   0       -       2       -

It turns each distinct player into a column and groups the games gives goals per game per player.

Community
  • 1
  • 1
edezzie
  • 1,657
  • 4
  • 14
  • 12
  • [SQL Server dynamic PIVOT query?](http://stackoverflow.com/questions/10404348/sql-server-dynamic-pivot-query) or [Pivots with dynamic columns in SQL Server](http://stackoverflow.com/questions/7822004/pivots-with-dynamic-columns-in-sql-server) – RichardTheKiwi Nov 02 '12 at 01:56

2 Answers2

9

You can use the PIVOT function. If you have a known number of columns, then you can hard-code the values:

select *
from
(
  select game, player, goals
  from yourtable
) src
pivot
(
  sum(goals)
  for player in ([John], [Paul], [Mark], [Luke])
) piv
order by game

See SQL Fiddle with Demo

If you have an unknown number of columns, then you can use dynamic sql:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(player) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT game, ' + @cols + ' from 
             (
                select game, player, goals
                from yourtable
            ) x
            pivot 
            (
                sum(goals)
                for player in (' + @cols + ')
            ) p '

execute(@query)

See SQL Fiddle with Demo

Taryn
  • 242,637
  • 56
  • 362
  • 405
2
select game,
  sum(case when player = 'john' then goals else 0 end) as john,
  sum(case when player = 'paul' then goals else 0 end) as paul,
  sum(case when player = 'mark' then goals else 0 end) as mark,
  sum(case when player = 'luke' then goals else 0 end) as luke
from t
group by game
order by game
Z .
  • 12,657
  • 1
  • 31
  • 56