2013-02-13 4 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 (DateTime) * 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, чтобы показать правильные группировки?

+0

Вам нужен запрос перекрестного стиле - взять посмотрите на http://stackoverflow.com/questions/7956908/sql-server-2008-cross-tab-query – Raad

+0

Почему бы просто не использовать свой существующий результат (что довольно неплохо) и перебрать его с помощью языка программирования, который вы используете ? Нормальным результатом является 2-мерный массив, содержащий атрибуты x-direction: attributes, y-direction: elements и VALUE в соответствующем соединении. Ваш желаемый результат будет содержать значения (определенный месяц) по оси x, для чего потребуется собственный * select column * для столбца. Это можно сделать, но я не думаю, что это хорошо. (Если вы хотите, чтобы tdo Display 10 Years, вам нужны 120 определений столбцов ...) – dognose

+0

Как называется ваша таблица продуктов? (Вам потребуется внешнее соединение от него, чтобы включить продукты, у которых не было продаж, записанных в указанные сроки, например Продукт 4 в представленном примере.) –

ответ

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

Смежные вопросы