2013-02-13 59 views
0

我们使用一票跟踪系统事件单位产品的数量,我想了许多票是如何为每月每个产品创建的信息:获取每月

 
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(日期时间) *产品名称(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以显示正确的分组?

+0

你需要一个交叉式的查询 - 花看看http://stackoverflow.com/questions/7956908/sql-server-2008-cross-tab-query – Raad 2013-02-13 11:36:21

+0

为什么不简单地使用你现有的结果(这是很好),并用你正在使用的编程语言迭代它?通常结果是2 dim阵列,其包含x方向:属性,y方向:元素和各个结点中的值。您所需的结果将包含x轴中的值(某个月),这需要每列都有一个自己的* select列*。它可以完成,但我不认为它很好。 (如果你想要tdo Display 10 Years,你需要120列定义...) – dognose 2013-02-13 11:37:20

+0

你的产品表叫什么? (您将需要通过外部联接来包含在指定时间范围内没有销售记录的产品,例如所提供示例中的产品4)。 – 2013-02-13 11:49:00

回答

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