透视SQL表

end*_*eka 0 sql pivot-table sql-server-2008-r2

我有一个带有"date"和"name"列的表.在这里你可以找到我的桌子样本: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
Run Code Online (Sandbox Code Playgroud)

我试过,但我得到这样的东西(所以我不发布错误的SQL查询......)

2012    2013    2014
  6       6       5 
Run Code Online (Sandbox Code Playgroud)

Tar*_*ryn 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;
Run Code Online (Sandbox Code Playgroud)

请参阅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;
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo