SQL Server 2008 Pivot и Concat

Извините, я новичок в SQL, поэтому мне было интересно, может ли кто-нибудь помочь мне со следующим:

у меня есть стол

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

Результат

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

person Loco_Ono    schedule 16.01.2014    source источник
comment
Вы пытались написать запрос для этого? Вы должны действительно показать свои попытки решения этой проблемы.   -  person Taryn    schedule 16.01.2014
comment
это не просто точка опоры, вы также объединяете потенциальные строки.   -  person Brett Schneider    schedule 16.01.2014
comment
Попробуйте использовать sqlfiddle.com для этого примера — это поможет вам и тем, кто пытается вам помочь.   -  person eebbesen    schedule 16.01.2014
comment
Спасибо, ребята, я собираюсь настроить учетную запись sqlfiddle, чтобы копаться и учиться. Очень признателен.   -  person Loco_Ono    schedule 16.01.2014


Ответы (1)


Для того, чтобы получить результат, вам придется сделать это в два этапа. Во-первых, вам нужно будет объединить все PlayerNames для каждого Position. Когда у вас есть список, вы можете преобразовать данные из строк в столбцы.

Поскольку вы используете SQL Server, существует несколько различных способов объединения данных. Вы можете использовать STUFF и 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

См. SQL Fiddle с демонстрацией. Это получает ваши данные в результате:

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

Теперь, когда ваши данные объединены, вы можете преобразовать данные с помощью агрегатной функции с выражением CASE или использовать PIVOT.

Объединить с 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

См. SQL Fiddle с демонстрацией.

ОСНОВНОЙ:

;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;

См. SQL Fiddle с демонстрацией.

Оба дают результат:

|    FORWARD |     CENTER |       DEFENSE |     GOALIE |
|------------|------------|---------------|------------|
|  Tom, John |  Dave, Bob |  Harry, James |  Mike, Tim |
person Taryn    schedule 16.01.2014
comment
Спасибо, bluefeet, я сейчас читаю о функции Stuff, спасибо, что подтолкнули меня к этому. Я никогда не видел его раньше. Еще раз спасибо за помощь. Сейчас я также настраиваю учетную запись SQL Fiddle. Спасибо. - person Loco_Ono; 16.01.2014