2015-03-05 4 views
0

У меня есть таблица базы данных билетов вЗапуск Всего по сгруппированным записям

+------------+-------------+------------+ 
| CategoryID | RequestDate | FixedDate | 
+------------+-------------+------------+ 
|   1 | 2014-01-01 | NULL  | 
|   1 | 2014-01-02 | 2014-01-05 | 
|   1 | 2014-01-28 | 2014-01-30 | 
|   2 | 2014-02-20 | NULL  | 
|   2 | 2014-03-15 | NULL  | 
|   2 | 2014-03-15 | 2014-03-20 | 
|   1 | 2014-03-15 | 2014-03-17 | 
+------------+-------------+------------+ 

Вот желаемый результат:

+-------+------+--------+-------+---------------+ 
| Month | Year | Opened | Fixed | Running_Total | 
+-------+------+--------+-------+---------------+ 
|  1 | 2014 |  3 |  2 |    1 | 
|  2 | 2014 |  1 |  0 |    2 | 
|  3 | 2014 |  3 |  2 |    3 | 
+-------+------+--------+-------+---------------+ 

В основном я ищу, чтобы получить текущую сумму всех открытых билетов в месяц мудрый. Я пытался с помощью CTE, но не мог этого сделать.

Любая помощь будет высоко оценена.

+0

Нет. Это Running_Total + Open-Fixed. – Ashish

ответ

1

Попробуйте это:

DECLARE @t TABLE (Req DATE, Fixed DATE) 

INSERT INTO @t 
VALUES ('20140101', NULL), 
     ('20140102', '20140105'), 
     ('20140128', '20140330'), 
     ('20140220', NULL), 
     ('20140301', NULL), 
     ('20140301', '20140320'), 
     ('20140301', '20140317'); 
WITH cte 
      AS (SELECT ROW_NUMBER() OVER (ORDER BY YEAR(Req), MONTH(Req)) AS Rn , 
         MONTH(Req) Month , 
         YEAR(Req) Year , 
         COUNT(*) AS Opened , 
         COUNT(Fixed) AS Fixed, 
         SUM(CASE WHEN MONTH(req) = MONTH(Fixed) THEN 1 ELSE 0 END) AS Closed      
       FROM  @t 
       GROUP BY MONTH(Req) , 
         YEAR(Req) 
      ) 
    SELECT Month, Year, Opened, Fixed , Closed , 
      (SELECT SUM(Opened) - SUM(Fixed) 
       FROM  cte c1 
       WHERE  c1.Rn <= cte.Rn 
      ) AS Running_Total 
    FROM cte 

Выход:

Month Year Opened Fixed Closed Running_Total 
1  2014 3  2  1  1 
2  2014 1  0  0  2 
3  2014 3  2  2  3 

Вы можете обойтись без CTE, но путем дублирования кода, к сожалению:

SELECT Month , 
     Year , 
     Opened , 
     Fixed , 
     Closed , 
     (SELECT SUM(Opened) - SUM(Fixed) 
      FROM  (SELECT ROW_NUMBER() OVER (ORDER BY YEAR(Req), MONTH(Req)) AS Rn , 
           COUNT(*) AS Opened , 
           COUNT(Fixed) AS Fixed 
         FROM  @t 
         GROUP BY MONTH(Req) , 
           YEAR(Req) 
        ) c1 
      WHERE  c1.Rn <= cte.Rn 
     ) AS Running_Total 
FROM (SELECT ROW_NUMBER() OVER (ORDER BY YEAR(Req), MONTH(Req)) AS Rn , 
        MONTH(Req) Month , 
        YEAR(Req) Year , 
        COUNT(*) AS Opened , 
        COUNT(Fixed) AS Fixed , 
        SUM(CASE WHEN MONTH(req) = MONTH(Fixed) THEN 1 
          ELSE 0 
         END) AS Closed 
      FROM  @t 
      GROUP BY MONTH(Req) , 
        YEAR(Req) 
     ) cte 
+0

Есть ли способ добавить счет всех билетов, которые были закрыты в том же месяце? – Ashish

+0

@ Ашиш, каков должен быть результат для ваших тестовых данных? –

+0

В этом случае он должен быть таким же, как Fixed. Но в идеале следует рассчитывать количество билетов, которые открываются и закрываются в том же месяце. – Ashish

0

Постройте запрос, который агрегирует в год и месяц и использовать это в курсоре, который вы затем перебираете, чтобы вычислить пробег t ОБЩИЙ.

declare @Month int; 
declare @Year int; 
declare @Opened int; 
declare @Fixed int; 
declare @Running_Total int = 0; 

declare @T table 
(
    Month int, 
    Year int, 
    Opened int, 
    Fixed int, 
    Running_Total int 
); 

declare C cursor local static forward_only read_only for 
    select T.Month, 
     T.Year, 
     count(*), 
     count(T.FixedDate) 
    from (
     select datepart(month, T.RequestDate) as Month, 
       datepart(year, T.RequestDate) as Year, 
       T.FixedDate 
     from dbo.YourTable as T 
     ) as T 
    group by T.Year, T.Month 
    order by T.Year, T.Month; 

open C; 
fetch next from C into @Month, @Year, @Opened, @Fixed; 

while @@fetch_status = 0 
begin 
    set @Running_Total = @Running_Total + @Opened - @Fixed; 

    insert into @T(Month, Year, Opened, Fixed, Running_Total) 
    values(@Month, @Year, @Opened, @Fixed, @Running_Total); 

    fetch next from C into @Month, @Year, @Opened, @Fixed; 
end; 

close C; 
deallocate C; 

select Month, Year, Opened, Fixed, Running_Total 
from @T; 
Смежные вопросы