SQL Server 2008 Pivot和Concat

时间:2014-01-16 14:47:50

标签: sql sql-server 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|
+---------+---------+------------+---------+

1 个答案:

答案 0 :(得分:2)

为了获得结果,您必须分两步完成。首先,您需要为每个PlayerNames连接所有Position。获得列表后,您可以将数据从行转移到列中。

由于您使用的是SQL Server,因此有几种不同的方法可以连接数据。您可以使用STUFFFOR 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 with Demo。这会将您的数据输入结果:

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

请参阅SQL Fiddle with Demo

两者都给出结果:

|    FORWARD |     CENTER |       DEFENSE |     GOALIE |
|------------|------------|---------------|------------|
|  Tom, John |  Dave, Bob |  Harry, James |  Mike, Tim |