【问题标题】:SQL for reporting based on events用于基于事件进行报告的 SQL
【发布时间】:2013-02-22 07:59:57
【问题描述】:

我有一个这样的事件表:

-----------------------------------------------------------
timestamp            |  station |  event_type   |  count
-----------------------------------------------------------
2013-02-22 01:00:00  |  1       |  log_in       |  -1
2013-02-22 01:05:00  |  1       |  alert        |  5
2013-02-22 01:08:00  |  1       |  alert        |  3
2013-02-22 01:10:00  |  1       |  log_out      |  -1
2013-02-22 01:30:00  |  2       |  log_in       |  -1
2013-02-22 01:31:00  |  2       |  alert        |  2
2013-02-22 01:35:00  |  2       |  log_out      |  -1
-----------------------------------------------------------

如何编写 SQL 来生成这样的报告:

--------------------------------------------------------------------------
station  | log_in               |  log_out               | count
--------------------------------------------------------------------------
1        | 2013-02-22 01:00:00  |  2013-02-22 01:10:00   | 8
2        | 2013-02-22 01:30:00  |  2013-02-22 01:35:00   | 2
--------------------------------------------------------------------------

基本上,我想总结一下登录和退出之间的警报。

有人能指出正确的方向吗?

更新:

JW 在下面的回答有效,但我在上表中犯了一个错误。对于警报事件,我不知道站号,所以表格应该如下所示。

-----------------------------------------------------------
timestamp            |  station |  event_type   |  count
-----------------------------------------------------------
2013-02-22 01:00:00  |  1       |  log_in       |  -1
2013-02-22 01:05:00  |  -1      |  alert        |  5
2013-02-22 01:08:00  |  -1      |  alert        |  3
2013-02-22 01:10:00  |  1       |  log_out      |  -1
2013-02-22 01:30:00  |  2       |  log_in       |  -1
2013-02-22 01:31:00  |  -1      |  alert        |  2
2013-02-22 01:35:00  |  2       |  log_out      |  -1
-----------------------------------------------------------

【问题讨论】:

  • 如果log_in记录没有对应的log_out记录,报告会怎样?
  • 理想情况下,SQL 应该处理这种情况,即丢失的 log_out 与最后一个警报事件的时间相同。

标签: mysql sql reporting


【解决方案1】:
SELECT  station, 
        MIN(timestamp) login,
        MAX(timestamp) logout,
        SUM(CASE WHEN count > 0 THEN count ELSE 0 END) count
FROM    tbaleName
GROUP   BY station

更新 1

SELECT  a.station, 
        a.login,
        a.logout,
        SUM(CASE WHEN count > 0 THEN count else 0 END) count
FROM
        (
          SELECT  station, 
                  MIN(timestamp) login,
                  MAX(timestamp) logout
          FROM    tableName2 
          GROUP   BY station
        ) a
        INNER JOIN tableName2 b
          ON b.timestamp BETWEEN a.logIN and a.logout AND
             a.station <> -1
GROUP   BY a.station, 
           a.login,
           a.logout

要获得更快的性能,请在 timestamp 列上添加 INDEX

【讨论】:

  • 您好 JW,您的回答很完美,但实际上我在原始帖子中犯了一个错误。对于警报事件,我不知道站号。在这种情况下,按站分组不起作用。
  • 根据你的新数据,你想要的结果是什么?
  • 您好 JW,所需的结果仍然相同。我只需要通过时间戳而不是站号来链接警报事件。
  • 你在用什么RDBMSSQL Server? MySQL? Oracle? DB2?等等。
  • 嗨,JW,你太棒了!您更新的答案完美无缺!我正在使用 MySQL。
猜你喜欢
  • 2014-05-28
  • 2012-09-18
  • 2015-02-21
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多