如何在SQL Server中运行总状态计数

时间:2018-06-10 05:32:23

标签: sql-server pivot

我有一张表保存任务状态的历史记录。任务的状态可以随时间变化,每次任务状态更改时,都会在表中创建具有新状态和修改日期的新条目。

示例:

Task ID| Status | Date Modified
-------+--------+---------------
100    |READY   | 2018-03-01
101    |READY   | 2018-03-01
102    |READY   | 2018-03-01
100    |RUNNING | 2018-03-02
101    |RUNNING | 2018-03-03
100    |FINISHED| 2018-03-03
102    |RUNNING | 2018-03-04
100    |READY   | 2018-03-04
101    |FINISHED| 2018-03-05
102    |FINISHED| 2018-03-07

如何查询"正在运行的总数"状态如下所示?

Date        | READY | RUNNING | FINISHED
------------+-------+---------+----------
2018-03-01  |     3 |       0 |        0
2018-03-02  |     2 |       1 |        0
2018-03-03  |     1 |       1 |        1
2018-03-04  |     1 |       2 |        0
2018-03-05  |     1 |       1 |        1
2018-03-06  |     1 |       1 |        1
2018-03-07  |     1 |       0 |        2

例如,在2018-03-07:

  • 任务100的状态为READY(上次更新为2018-03-04的READY)
  • 任务101的状态已完成(上次更新至2018-03-05完成)
  • 任务102的状态已完成(上次更新为2018-03-07完成)

因此,2018-03-07的状态为READY:1,RUNNING:0,FINISHED:2

我在网上看到了几个使用分区的示例,但我似乎无法将这些应用到这种情况中。

1 个答案:

答案 0 :(得分:3)

您需要计算每个ID的最新状态,而不是运行总计吗?

这样的东西应该有用,但是你需要一个日历表(一个真实的或一个计数器):

select
  c.date,
  sum(case when X.status = 'Ready' then 1 else 0 end),
  sum(case when X.status = 'Running' then 1 else 0 end),
  sum(case when X.status = 'Finished' then 1 else 0 end)
from
  calendar c
  outer apply (
    select ID, Status from
    (
        select
            ID,
            row_number() over (partition by ID order by DateModified desc) RN
        from
            yourtable t
        where
            t.DateModified <= c.date
    ) X
    where X.RN = 1
  ) X
group by
  c.date

这会收集每天每个ID的最新状态,然后计算计数。可能存在语法错误,但这样的事情应该有效。