SQLite查询;按小时和按设备分组

时间:2015-09-26 22:15:42

标签: sql sqlite select

我有一个计数器的SQLite数据库,计数如下:

       DateTime        |Gate|Count
-----------------------+----+-----
2015-09-23T19:23:01.000|   2|  345
2015-09-23T19:41:08.000|   2|  346
2015-09-23T19:41:30.000|   3|  654
2015-09-23T19:44:00.000|   4|  556
2015-09-23T21:13:47.000|   2|  348

我想确定每小时每个门的数量。在上表中,Gate#2在19:00小时内计数为1,在21:00小时计数为2。

我设法获得以下选择声明:

SELECT  strftime('%Y-%m-%dT%H:00:00.000', DateTime),
          max(Count) - min(Count) 
FROM GateTbl 
WHERE Gate='2' 
GROUP by strftime('%Y-%m-%dT%H:00:00.000', DateTime);

起初我似乎走在了正确的轨道上,因为这几乎完全符合我的要求。但它只适用于一次一个门,当我想要返回所有门的每小时计数。我也开始意识到它不会像上面的21:00一样工作,那个小时只有一个条目。

我无法在SQL语句中看到这样做的方法,我希望有人在这里。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:3)

您只需将Gate添加到group byselect

SELECT gate, strftime('%Y-%m-%dT%H:00:00.000', DateTime),
       max(Count) - min(Count) 
FROM GateTbl 
GROUP by gate, strftime('%Y-%m-%dT%H:00:00.000', DateTime);

编辑:

哎呀,对不起。您实际需要的是 next 小时的第一个计数。 SQL具有很好的功能,lag()。但不是SQLite。但是,您可以使用相关子查询来执行此操作:

WITH gh as (
      SELECT gate, strftime('%Y-%m-%dT%H:00:00.000', DateTime) as dt,
             MIN(Count) as mincount, MAX(count) as maxcount
      FROM GateTbl 
      GROUP by gate, strftime('%Y-%m-%dT%H:00:00.000', DateTime)
     )
SELECT gh.gate, gh.dt,
       COALESCE(gh.next_mincount, gh.maxcount) - gh.mincount
FROM (SELECT gh.*,
             (SELECT gh2.mincount
              FROM gh gh2
              WHERE gh2.gate = gh.gate AND gh2.dt > gh.dt
              ORDER BY gh2.dt
              LIMIT 1
             ) as next_mincount
      FROM gh
     ) gh;

coalesce()仅适用于最后一小时。这使用了该小时内的最后一个时间戳。如果只有一个,那么那个小时就会得到0。