2013-02-13 41 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