透视SQL表

时间:2014-09-08 12:57:53

标签: sql sql-server-2008-r2 pivot-table

我有一个带有列的表" date"和"名称"。 在这里,您可以找到我的表格样本:http://sqlfiddle.com/#!2/eddede/1

我需要做的是计算每个人每年的行数。如果此人在X年没有值,则必须看到0.名称的顺序必须是当前年份DESC的总数,因此目前:2014年。

我可以计算每年/姓名,但不确定我是否需要透视表:http://sqlfiddle.com/#!2/eddede/3

我希望结果看起来像这样:

NAME        2012    2013    2014   TOTAL
Person B      2       2       2      6
Person C      0       1       2      3
Person A      4       3       1      8

我已经尝试了,但我得到了类似的内容(所以我不会发布错误的SQL查询...)

2012    2013    2014
  6       6       5 

2 个答案:

答案 0 :(得分:7)

您可以使用聚合函数获取结果,其中包含一些条件逻辑,如CASE表达式:

select 
  name,
  sum(case when year(date) = 2012 then 1 else 0 end) [2012],
  sum(case when year(date) = 2013 then 1 else 0 end) [2013],
  sum(case when year(date) = 2014 then 1 else 0 end) [2014],
  count(*) Total
from list
group by name;

请参阅SQL Fiddle with Demo

现在,如果年份值未知,那么您将需要使用动态SQL。这将创建您需要执行的SQL字符串:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @orderby nvarchar(max)

select @cols 
  = STUFF((SELECT  ',' + QUOTENAME(year(date)) 
           from list
           group by year(date)
           order by year(date)
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @orderby = 'ORDER BY ['+cast(year(getdate()) as varchar(4)) + '] desc'

set @query = 'SELECT name, ' + @cols + ', Total
            from 
            (
                select name, year(date) dt,
                   count(*) over(partition by name) Total
                from list
            ) x
            pivot 
            (
                count(dt)
                for dt in (' + @cols + ')
            ) p '+ @orderby


exec sp_executesql @query;

请参阅SQL Fiddle with Demo

答案 1 :(得分:2)

我认为这就是你要找的东西:

SELECT  
  name,  
  SUM(if(year(date) = 2012, 1, 0)) AS '2012', 
  SUM(if(year(date) = 2013, 1, 0)) AS '2013', 
  SUM(if(year(date) = 2014, 1, 0)) AS '2014' 
FROM list 
GROUP BY name;

并且总计:)

SELECT
  t.name,
  t.`2012`,
  t.`2013`,
  t.`2014`,
  t.`2012` + t.`2013` + t.`2014` as total
FROM
(
SELECT  
  name,  
  SUM(if(year(date) = 2012, 1, 0)) AS `2012`, 
  SUM(if(year(date) = 2013, 1, 0)) AS `2013`, 
  SUM(if(year(date) = 2014, 1, 0)) AS `2014`
FROM list 
GROUP BY name
) as t