查看日期或时间顺序中的分组记录。可能是按级别分组的日志表

时间:2014-01-10 14:43:34

标签: sql sql-server tsql

假设您的SQL Server(EDIT:prensently SQL Server 2008)数据库中有一个表,如下所示:

Date                    Id State
=================================
2013-09-12 15:02:41,844 1 OK
2013-09-12 15:02:41,844 2 OK
2013-09-12 15:02:41,844 3 ERROR
2013-09-12 15:02:41,844 4 ERROR
2013-09-12 15:02:41,844 5 ERROR
2013-09-13 15:02:41,844 1 ERROR
2013-09-14 15:02:41,844 1 OK
2013-09-15 15:02:41,844 1 ERROR
2013-09-15 15:02:41,844 2 ERROR

表的purpouse是保存记录状态。我写了这个表,但现在我无法弄清楚如何查询它以查看时间序列中不同状态的概述。

我正在寻找的结果是:

2013-09-12 16:00:00 OK 2
2013-09-12 16:00:00 ERROR 3
2013-09-13 16:00:00 OK 1
2013-09-13 16:00:00 ERROR 4
2013-09-14 16:00:00 OK 2
2013-09-14 16:00:00 ERROR 3
2013-09-15 16:00:00 OK 0
2013-09-15 16:00:00 ERROR 5

编辑:我想要实现的是对象状态的逐日视图。哪些对象有错误,哪些对象有问题。也许车库会是一个更好的例子,但我会坚持这一点。

  • 在12日,3个对象有ERROR,2个对象有OK。
  • 13日,一个对象从OK变为Error。我现在有4个处于ERROR状态的对象和一个可以正常的对象。
  • 14日我的id为1的对象已修复,我现在又回到两个OK>和三个有ERROR状态的对象

我已经找到(找到)如何生成一系列日期(不使用变量声明),如下所示:

;WITH dates
AS (
    SELECT CAST('2013-12-17 16:00:00' AS DATETIME) 'date'

    UNION ALL

    SELECT DATEADD(dd, 1, t.DATE)
    FROM dates t
    WHERE DATEADD(dd, 1, t.DATE) <= GETDATE()
    )
SELECT dates.DATE   
FROM dates

我有一个查询执行相关分组(我认为),提供所需的输出(和点):

Date State Count(state)
=======================    
2013-09-12 16:00:00 OK 2
        2013-09-12 16:00:00 ERROR 3
        2013-09-13 16:00:00 ERROR 1
        2013-09-14 16:00:00 OK 1
        2013-09-15 16:00:00 ERROR 1

所以问题是,你如何将日期序列与我的分组结果结合起来以达到预期的效果。

1 个答案:

答案 0 :(得分:1)

使用SQL Server 2012提供窗口功能,您可以使用以下查询:

SELECT date,
       sum(ok_mod) over (order by date) as ok
FROM (
  SELECT date,
         sum(case when state = 'OK' then 1
                  when state = 'ERROR' and prev_state is not null then -1
                  else 0
             end) as ok_mod
  FROM (
    SELECT date, id, state,
           lag(state) over (partition by id order by date) prev_state
    FROM data
  ) AS data
  GROUP BY date
) AS data
ORDER BY date;

这只给你OK部分,但你也可以很容易地联合ERROR部分的相应查询。 SQL小提琴here

使用2008版本imho,如果没有程序或非常复杂的查询,您将无法实现。