如何在以下场景中应用数据透视表

时间:2013-03-21 07:33:35

标签: sql sql-server tsql pivot

我有下表

Name    Month   Year    Count
----------------------------
xxx     12      2012    24
xxx     1       2013    42
xxx     2       2013    23
yyy     12      2012    34
yyy     1       2013    12
yyy     2       2013    54

我想将其转换为以下格式,

Name    Dec-12  Jan-13  Feb-13
--------------------------------
xxx     24      42      23
yyy     34      12      54

如何应用数据透视?

3 个答案:

答案 0 :(得分:3)

由于您使用的是SQL Server,因此有几种方法可以将数据从行转移到列中。

如果您的值有限或者您有一定数量的值,那么您可以使用静态数据透视表对值进行硬编码:

select name, [Dec_12], [Jan_13], [Feb_13]
from
(
  select name,
    left(datename(month, dateadd(month, month, 0) -1), 3) +'_'+right(cast(year as varchar(4)), 2) MY,
    [count]
  from yourtable
) src
pivot
(
  sum(count)
  for my in ([Dec_12], [Jan_13], [Feb_13])
) piv;

SQL Fiddle with Demo

现在,如果您有未知数量的值,那么您将需要实现动态SQL来生成结果:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(my) 
                    from 
                    (
                      select left(datename(month, dateadd(month, month, 0) -1), 3) +'_'+right(cast(year as varchar(4)), 2) my,
                         CAST(
                            CAST(year AS VARCHAR(4)) +
                            RIGHT('0' + CAST(month AS VARCHAR(2)), 2) +
                            '01'
                         AS DATETIME) fulldate
                      from yourtable
                    ) t
                    group by my, fulldate
                    order by fulldate 
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT name, ' + @cols + ' 
              from 
             (
                select name,
                  left(datename(month, dateadd(month, month, 0) -1), 3) +''_''+right(cast(year as varchar(4)), 2) MY,
                  [count]
                from yourtable
            ) x
            pivot 
            (
                sum(count)
                for my in (' + @cols + ')
            ) p '

execute(@query)

SQL Fiddle with Demo

与此版本和静态版本的区别在于,如果您需要未知数量的日期,或者希望在新日期可用时自动更新,则会返回新数据而不更改代码。

两个查询的结果是:

| NAME | DEC_12 | JAN_13 | FEB_13 |
-----------------------------------
|  xxx |     24 |     42 |     23 |
|  yyy |     34 |     12 |     54 |

答案 1 :(得分:1)

试试这个:

WITH CTE
AS
(
  SELECT
    Name, 
    CAST(Month AS VARCHAR(2)) + '-' + CAST(Year AS VARCHAR(4)) AS MonthYear,
    [Count]
  FROM tablename
)
SELECT 
  Name,
  [12-2012] AS 'Dec-12', 
  [1-2013]  AS 'Jan-13', 
  [2-2013]  AS 'Feb-13'
FROM CTE
PIVOT
(  
   MAX([Count])
   FOR MonthYear IN([12-2012], 
                    [1-2013], 
                    [2-2013])
) AS p;

SQL Fiddle Demo

答案 2 :(得分:1)

  SELECT t.name
         , MAX(CASE
                 WHEN t.month=12 AND t.year = 2012
                   THEN count
                 ELSE NULL
               END) AS "Dec_12"
         , MAX(CASE
                 WHEN t.month=1 AND t.year = 2013
                   THEN count
                 ELSE NULL
               END) AS "Jan_13"
         , MAX(CASE
                 WHEN t.month=2 AND t.year = 2013
                   THEN count
                 ELSE NULL
               END) AS "Feb_13"
    FROM table t
GROUP BY t.name
;