Question

Sorry I'm new to SQL so I was wondering if anyone could help me with the following:

I have a table

+--------+----------+
|Position|PlayerName|
+--------+----------+
|Forward |Tom       |
+--------+----------+
|Forward |John      |
+--------+----------+
|Center  |Dave      |
+--------+----------+
|Defense |Harry     |
+--------+----------+
|Center  |Bob       |
+--------+----------+
|Defense |James     |
+--------+----------+
|Goalie  |Mike      |
+--------+----------+
|Goalie  |Tim       |
+--------+----------+

Result

+---------+---------+------------+---------+
|Forward  |Center   |Defense     |Goalie   |
+---------+---------+------------+---------+
|Tom, John|Dave, Bob|Harry, James|Mike, Tim|
+---------+---------+------------+---------+
Was it helpful?

Solution

In order to get the result, you will have to do this in two steps. First, you will need to concatenate all of the PlayerNames for each Position. Once you have the list, then you can pivot the data from rows into columns.

Since you are using SQL Server, there are a few different ways to concatenate the data. You can use STUFF and FOR XML PATH:

select t1.position,
  STUFF(
       (SELECT ', ' + t2.PlayerName
        FROM yourtable t2
        where t1.position = t2.position
        FOR XML PATH (''))
        , 1, 1, '')  AS PlayerName
from yourtable t1

See SQL Fiddle with Demo. This gets your data into the result:

| POSITION |    PLAYERNAME |
|----------|---------------|
|  Forward |     Tom, John |
|   Center |     Dave, Bob |
|  Defense |  Harry, James |

Now that your data has been concatenated, then you can convert the data using an aggregate function with a CASE expression or you can use PIVOT.

Aggregate with CASE:

;with cte as
(
  select t1.position,
    STUFF(
         (SELECT ', ' + t2.PlayerName
          FROM yourtable t2
          where t1.position = t2.position
          FOR XML PATH (''))
          , 1, 1, '')  AS PlayerNames
  from yourtable t1
)
select 
  max(case when position = 'Forward' then PlayerNames end) Forward,
  max(case when position = 'Center' then PlayerNames end) Center,
  max(case when position = 'Defense' then PlayerNames end) Defense,
  max(case when position = 'Goalie' then PlayerNames end) Goalie
from cte

See SQL Fiddle with Demo

PIVOT:

;with cte as
(
  select t1.position,
    STUFF(
         (SELECT ', ' + t2.PlayerName
          FROM yourtable t2
          where t1.position = t2.position
          FOR XML PATH (''))
          , 1, 1, '')  AS PlayerName
  from yourtable t1
)
select Forward, Center, Defense, Goalie
from cte
pivot
(
  max(playername)
  for position in (Forward, Center, Defense, Goalie)
) piv;

See SQL Fiddle with Demo.

Both give a result:

|    FORWARD |     CENTER |       DEFENSE |     GOALIE |
|------------|------------|---------------|------------|
|  Tom, John |  Dave, Bob |  Harry, James |  Mike, Tim |
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top