SQL Server活动记录按月计算

时间:2018-01-19 02:10:53

标签: sql sql-server sql-server-2008 tsql

我创建了一个存储事件故障单的数据库。 我创建了一个事实和一些维度表。

以下是一些示例数据

+---------------------+--------------+--------------+-------------+------------+
| LastModifiedDateKey | TicketNumber |    Status    | factCurrent |    Date    |
+---------------------+--------------+--------------+-------------+------------+
|                2774 | T:9992260    | Open         | 1           | 4/12/2017  |
|                2777 | T:9992805    | Open         | 1           | 7/12/2017  |
|                2777 | T:9993068    | Open         | 1           | 7/12/2017  |
|                2777 | T:9993098    | Open         | 0           | 7/12/2017  |
|                2793 | T:9993098    | Acknowledged | 0           | 23/12/2017 |
|                2928 | T:9993098    | Closed       | 1           | 5/01/2018  |
|                2777 | T:9993799    | Open         | 0           | 7/12/2017  |
|                2928 | T:9993799    | Closed       | 1           | 5/01/2018  |
|                2778 | T:9994729    | Open         | 1           | 8/12/2017  |
|                2774 | T:9994791    | Open         | 0           | 4/12/2017  |
|                2928 | T:9994791    | Closed       | 1           | 5/01/2018  |
|                2777 | T:9994912    | Open         | 1           | 7/12/2017  |
|                2778 | T:9995201    | Open         | 0           | 8/12/2017  |
|                2793 | T:9995201    | Closed       | 1           | 23/12/2017 |
|                2931 | T:9718629    | Open         | 1           | 8/01/2018  |
|                2933 | T:9718629    | Closed       | 1           | 10/01/2018 |
|                2932 | T:9855664    | Open         | 1           | 9/01/2018  |
|                2931 | T:9891975    | Open         | 1           | 8/01/2018  |
+---------------------+--------------+--------------+-------------+------------+

我想要一个查询,它会在每个月末给我打开总票数。 在数据1月应该有8和2月2日。 注意:票证可以包含多个具有相同状态的行,因为维度键已更改,或者同一个月中的多个行具有不同的状态。例如T:。9993098

2 个答案:

答案 0 :(得分:2)

此方法首先使用ROW_NUMBER来识别每个月/每年的每张票的最新记录。假设一个月中的最新记录将包含该月结束的票证的状态。然后,它聚合在这个修改过的表上,只计算在月份处于打开状态的票据。

SELECT
    YEAR(Date) + "-" + MONTH(Date) AS date,
    COUNT(*) AS num_open_tickets
FROM
(
    SELECT *,
        ROW_NUMBER() OVER (PARITION BY YEAR(Date), MONTH(Date), TicketNumber
                           ORDER BY BY Date DESC) rn
    FROM yourTable
) t
WHERE t.rn = 1 AND t.Status = 'Open'
GROUP BY
    YEAR(Date) + "-" + MONTH(Date);

答案 1 :(得分:0)

首先,我会产生几个月。然后执行打开的累计计数减去关闭。唉,这有点棘手,因为票证的重复行和你使用旧版本的SQL Server。

但是。 。 。你可以这样做:

with months as (
      select dateadd(day, 1 - day(min(date)), min(date)) as mon_start,
             max(date) as max_date
      from sample
      union all
      select dateadd(month, 1, mon_start), max_date
      from months
      where dateadd(month, 1, mon_start) < max_date
     )
select m.mon_end,
       (select count(distinct case when status = 'Open' then ticket end) -
               count(distinct case when status = 'Closed' then ticket end)
        from sample s
        where s.date <= m.mon_end
       ) as open_tickets
from (select dateadd(day, -1, mon_start) as mon_end
      from months
     ) m;

这使用递归CTE来生成月份。生成这几个月的第一天更容易,然后在一天之后减去一天(在2月的最后一天加1个月的日期是什么时候?)

其余的使用相关子查询来计算该日期打开的门票数量。