使用sql创建数据透视表

时间:2013-11-25 18:42:12

标签: sql sql-server pivot

我正在尝试在sql中创建一个数据透视表但是遇到了困难。这是我的问题:我的数据库中有一个名为' statusreason'的列,我需要提供过去一周每个状态的总和。我的设置如下:

StatusReason Count

我需要调整此表格,使其显示如下:

enter image description here

上表中没有显示许多状态原因,因为它们在过去一周内没有出现过。

用于生成结果集的查询是:

select inv.statusreason
  , count(inv.statusreason) as 'StatusCount'
from invoicetbl inv (nolock)
inner join trucktbl tru (nolock) on inv.tru_key = tru.tru_key
where inv.client_key = 123
  and inv.createdate > getdate() - 7
group by inv.statusreason

如果这还没有足够的信息,请告知我可以添加哪些内容来改进问题。

感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:2)

由于您希望将数据行转换为列,因此需要PIVOT数据。这可以通过多种方式完成。

如果您将返回有限数量的值,则可以使用带有CASE表达式的聚合函数:

select 
    count(case when statusreason = 181 then 1 end) [181],
    count(case when statusreason = 20 then 1 end) [20],
    count(case when statusreason = 212 then 1 end) [212],
    count(case when statusreason = 232 then 1 end) [232]
from
(
    select inv.statusreason
    from invoicetbl inv (nolock)
    inner join trucktbl tru (nolock) 
        on inv.tru_key = tru.tru_key
    where inv.client_key = 123
      and inv.createdate > getdate() - 7
) d;

或者您可以使用PIVOT功能:

select [181], [20], [212], [232]
from
(
    select inv.statusreason
    from invoicetbl inv (nolock)
    inner join trucktbl tru (nolock) 
        on inv.tru_key = tru.tru_key
    where inv.client_key = 123
      and inv.createdate > getdate() - 7
) d
pivot
(
    count(statusreason)
    for statusreason in ([181], [20], [212], [232])
) p;

如果您将返回未知数量的值,那么您将需要查看使用动态SQL。这将创建一个sql字符串,然后执行。

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(statusreasons ) 
                    from statusreasontbl
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ' + @cols + ' 
            from 
            (
                select inv.statusreason
                from invoicetbl inv (nolock)
                inner join trucktbl tru (nolock) 
                    on inv.tru_key = tru.tru_key
                where inv.client_key = 123
                  and inv.createdate > getdate() - 7
            ) x
            pivot 
            (
                count(statusreason)
                for statusreason in (' + @cols + ')
            ) p '

execute sp_executesql @query;