【问题标题】:Time series group by day and kind按天和种类分组的时间序列
【发布时间】:2026-01-28 02:25:01
【问题描述】:

我使用以下命令创建一个表:

CREATE TABLE IF NOT EXISTS stats (
  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  session_kind INTEGER NOT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)

我使用以下命令插入一些时间序列数据:

INSERT INTO stats (session_kind) values (?1)

在执行了几次插入命令后,我有一些时间序列数据如下:

id    session_kind    ts
-----------------------------------------
1     0               2020-04-18 12:59:51  // day 1
2     1               2020-04-19 12:59:52  // day 2
3     0               2020-04-19 12:59:53
4     1               2020-04-19 12:59:54
5     0               2020-04-19 12:59:55
6     2               2020-04-19 12:59:56
7     2               2020-04-19 12:59:57
8     2               2020-04-19 12:59:58
9     2               2020-04-19 12:59:59
10    0               2020-04-20 12:59:51  // day 3
11    1               2020-04-20 12:59:52
12    0               2020-04-20 12:59:53
13    1               2020-04-20 12:59:54
14    0               2020-04-20 12:59:55
15    2               2020-04-20 12:59:56
16    2               2020-04-20 12:59:57
17    2               2020-04-20 12:59:58
18    2               2020-04-21 12:59:59  // day 4

我想要一个命令,按日期对我的数据进行分组,从最近的一天到最少的日期以及每个 session_kind 的数量,如下所示(我不想给这个命令提供任何参数):

0    1    2    ts
-------------------------
0    0    1    2020-04-21  // day 4
3    2    3    2020-04-20  // day 3
2    2    4    2020-04-19  // day 2
1    0    0    2020-04-18  // day 1

如何按上述方式对我的数据进行分组?

【问题讨论】:

    标签: sql sqlite date group-by count


    【解决方案1】:

    你可以做条件聚合:

    select
        sum(session_kind= 0) session_kind_0,
        sum(session_kind= 1) session_kind_1,
        sum(session_kind= 2) session_kind_2,
        date(ts) ts_day
    from mytable
    group by date(ts)
    order by ts_day desc
    

    如果你想要一些动态的东西,那么将结果放在行而不是列中可能会更简单:

    select date(ts) ts_day, session_kind, count(*) cnt
    from mytable
    group by date(ts), session_kind
    order by ts_day desc, session_kind
    

    【讨论】:

    • 谢谢,这行得通。是否真的有必要为每个session_kind 明确请求,还是可以迭代(自动)处理?我的意思是,如果在某个时候,session_kind 增加到 3、4 或更多,那么我需要为每个新添加的session_kind 修改 SQL 查询。
    • 我猜这不是完美的解决方案,因为它不是一个通用的解决方案。在他的例子中,他只展示了 3 种会话。但是,如果他有 100 个 session_kinds 怎么办?他必须赚100 sum()吗?
    • @MichelGuimarães:是的,如果你想处理更多的session_kinds,那么你需要扩展select 子句;这是因为 SQL 查询返回一组 fixed 列(因此这不能是动态的 - 除非您使用 dynamic SQL,这确实是一个不同的野兽)。我在答案中添加了另一个查询,将结果放在行而不是列中:这将是 100% 动态的。
    • 它说:“没有这样的列:datets_day”
    • @sanchop22:对不起,错字。固定。
    【解决方案2】:

    如果我理解正确,您只想对这些值求和:

    select date(timestamp),
           sum(case when session_kind = 1 then 1 else 0 end) as cnt_1,
           sum(case when session_kind = 2 then 1 else 0 end) as cnt_2,
           sum(case when session_kind = 3 then 1 else 0 end) as cnt_3
    from t
    group by date(timestamp);
    

    你也可以简化:

    select date(timestamp),
           sum( session_kind = 1 ) as cnt_1,
           sum( session_kind = 2 ) as cnt_2,
           sum( session_kind = 3 ) as cnt_3
    from t
    group by date(timestamp);
    

    【讨论】: