获取每个产品每月的事件数量

时间:2013-02-13 11:32:01

标签: sql sql-server pivot grouping

我们正在使用故障单跟踪系统,我希望了解每月为每种产品创建的故障单数量:

Product Jan 12  Feb 12
Product 1   130  99
Product 2   13  14
Product 3   7   9
Product 4       
Product 5   13  7
Product 6   22  31
Product 7       
Product 8   10  5

数据库:MS SQL Server 2008 表名:incidentbase 相关领域: * Createdon(日期时间) * Productname(nvarchar)

我可以使用以下SQL获取信息,但不能使用上面显示的格式:

Select (convert(varchar(7), CreatedOn, 102)) as 'month', Productname as Product,  COUNT(*) as number
from Incidentbase
where createdon >= '2011-01-01'
group by Productname, (convert(varchar(7), CreatedOn, 102))
ORDER BY (convert(varchar(7), i.CreatedOn, 102))
month   Product number
2011.01 Product1    1
2011.01 Product2    93
2011.01 Product3    20
2011.02 Product1    98
2011.02 Product2    23
2011.02 Product3    7

知道如何更改SQL以显示正确的分组吗?

1 个答案:

答案 0 :(得分:1)

在SQL Server中,您可以实现PIVOT函数来转换列中行的数据:

select productname,
  [2011.01], 
  [2011.02]
from
(
  select ProductName,
    (convert(varchar(7), CreatedOn, 102)) as 'month'
  from Incidentbase
  where createdon >= '2011-01-01'
) src
pivot
(
  count(month)
  for month in ([2011.01], [2011.02])
) piv

请参阅SQL Fiddle with Demo

如果您要将未知数量的日期转换为列,则可以使用动态SQL:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME((convert(varchar(7), CreatedOn, 102))) 
                    from Incidentbase
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ProductName,' + @cols + ' from 
             (
                  select ProductName,
                    (convert(varchar(7), CreatedOn, 102)) as month
                  from Incidentbase
                  where createdon >= ''2011-01-01''
            ) x
            pivot 
            (
                count(month)
                for month in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle with Demo

如果要将日期传递给动态查询,那么您将使用稍微不同的代码版本:

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

set @startdate = '2011-01-01'

select @cols = STUFF((SELECT distinct ',' + QUOTENAME((convert(varchar(7), CreatedOn, 102))) 
                    from Incidentbase
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ProductName,' + @cols + ' from 
             (
                  select ProductName,
                    (convert(varchar(7), CreatedOn, 102)) as month
                  from Incidentbase
                  where createdon >= '+convert(varchar(10), @startdate, 120)+'
            ) x
            pivot 
            (
                count(month)
                for month in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle with Demo