ClickHouse 聚合 - 按天/月/年分组(时间戳)?

Posted

技术标签:

【中文标题】ClickHouse 聚合 - 按天/月/年分组(时间戳)?【英文标题】:ClickHouse Aggregates - GROUP BY DAY/MONTH/YEAR(timestamp)? 【发布时间】:2021-04-29 01:34:54 【问题描述】:

ClickHouse 中是否有办法使用时间戳值执行 GROUP BY DAY/MONTH/YEAR()?在将 mysql 查询重写为 ClickHouse 时很难弄清楚。我的 MySQL 查询看起来像这样......

SELECT COUNT(this), COUNT(that) FROM table WHERE something = x AND stamp BETWEEN startdate AND enddate

SELECT COUNT(this), COUNT(that) FROM table WHERE something = x AND stamp BETWEEN startdate AND enddate GROUP BY DAY(stamp)

SELECT COUNT(this), COUNT(that) FROM table WHERE something = x AND stamp BETWEEN startdate AND enddate GROUP BY MONTH(stamp)

SELECT COUNT(this), COUNT(that) FROM table WHERE something = x AND stamp BETWEEN startdate AND enddate GROUP BY YEAR(stamp)

在 MySQL 中相当简单和缓慢,但我不知道如何在 ClickHouse 中进行聚合。

谢谢!

【问题讨论】:

怎么知道哪个计数属于哪一天、哪一个月、哪一年等 就是这样。 MySQL 知道并具有 DAY()、MONTH() 和 YEAR() 函数来恭敬地将时间戳转换为 GROUP BY 子句中的每一天、每一个月或每一年。 ClickHouse 没有。想知道如何为 ClickHouse 重写它。谢谢! 【参考方案1】:

获取部分日期使用函数toYear,toMonth,toDayOfMonth通过下一种方式:

SELECT
    toMonth(time) AS month,
    count()
FROM 
(
    SELECT
        number,
        addDays(now(), number) AS time
    FROM numbers(8)
)
GROUP BY month

/*
┌─month─┬─count()─┐
│     1 │       7 │
│     2 │       1 │
└───────┴─────────┘
*/

要获得多个分组集,请使用WITH ROLLUP-modifier:

SELECT
    toYear(time) AS year,
    toMonth(time) AS month,
    toDayOfMonth(time) AS day,
    count()
FROM 
(
    SELECT
        number,
        addDays(now(), number) AS time
    FROM numbers(8)
)
GROUP BY
    year,
    month,
    day
    WITH ROLLUP

/*
┌─year─┬─month─┬─day─┬─count()─┐
│ 2021 │     2 │   1 │       1 │ // day
│ 2021 │     1 │  29 │       1 │ // day
│ 2021 │     1 │  31 │       1 │ // day
│ 2021 │     1 │  26 │       1 │ // day
│ 2021 │     1 │  25 │       1 │ // day
│ 2021 │     1 │  28 │       1 │ // day
│ 2021 │     1 │  30 │       1 │ // day
│ 2021 │     1 │  27 │       1 │ // day
│ 2021 │     1 │   0 │       7 │ // month
│ 2021 │     2 │   0 │       1 │ // month
│ 2021 │     0 │   0 │       8 │ // year
│    0 │     0 │   0 │       8 │
└──────┴───────┴─────┴─────────┘
*/

【讨论】:

我猜应该可以。谢谢!接受答案! 不包括计数为 0 的行。 COALESCE(COUNT(this), 0) 现在帮助 GROUP BY 返回计数为 0 或 sum() 的行。任何想法如何做到这一点? 考虑使用ORDER BY WITH FILL。

以上是关于ClickHouse 聚合 - 按天/月/年分组(时间戳)?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL TIMESTAMP 列 - 按天分组

Grafana 图表按天或月分组?

按天周月统计数据

MySQL按天/周/月/季度/半年/年统计数据

oracle按天,周,月,季度,年查询排序

Clickhouse 数组连接与左连接和计算计数