ClickHouse 的月活跃用户数

Monthly active users in ClickHouse

由于 ClickHouse 不支持查询的 WITH 子句,我在执行计算 MAU 的查询时遇到了麻烦(每月活跃用户每天计算,30 天的范围也在每天移动)。 在 Postgres 中我会这样做:

WITH days AS (
  SELECT created_at::DATE AS day,
  FROM events
  WHERE created_at > '2019-04-01'
  GROUP BY 1 
)
SELECT day,
         (SELECT count(distinct user_id)
          FROM events
          WHERE events.created_at::DATE BETWEEN days.day-29 AND days.day
            AND created_at > '2019-04-01'
         ) AS mau
FROM days

想要的结果看起来像这样

┌────────day─┬──mau─┐
│ 2019-04-04 │ 1278 │
│ 2019-04-05 │ 1375 │
│ 2019-04-06 │ 1162 │
│ 2019-04-07 │ 1237 │
│ 2019-04-08 │ 1272 │
│ 2019-04-09 │ 1263 │
│ 2019-04-10 │ 1336 │
│ 2019-04-11 │ 1457 │
│ 2019-04-12 │ 1286 │
│ 2019-04-13 │ 1210 │
│ 2019-04-14 │ 1253 │
│ 2019-04-15 │ 2342 │
│ 2019-04-16 │ 1464 │
│ 2019-04-17 │ 1513 │
│ 2019-04-18 │ 1158 │
│ 2019-04-19 │ 1207 │
│ 2019-04-20 │ 1222 │
│ 2019-04-21 │ 1054 │
│ 2019-04-22 │ 1505 │
│ 2019-04-23 │ 5287 │
│ 2019-04-24 │ 4367 │
│ 2019-04-25 │ 3624 │
│ 2019-04-26 │ 2415 │
│ 2019-04-27 │ 1962 │
│ 2019-04-28 │ 2032 │
│ 2019-04-29 │ 2547 │
│ 2019-04-30 │ 4059 │
└────────────┴──────┘

您始终可以直接内联 CTE,例如

SELECT
    d.day,
    COUNT(DISTINCT e.user_id) AS mau
FROM
(
    SELECT created_at::DATE AS day,
    FROM events
    WHERE created_at > '2019-04-01'
    GROUP BY 1 
) d
LEFT JOIN events e
    ON e.created_at::DATE BETWEEN d.day-29 AND d.day
GROUP BY
    d.day;

上面的 CTE 已被子查询别名替换为 d。我继续重构您的查询以使用左连接,替换您拥有的相关子查询。

您可以尝试这样的操作:

SELECT
    created_at,
    uniqExact(user_id) AS mau
FROM
(
    SELECT
        created_at + n AS created_at,
        user_id
    FROM
    (
        SELECT
            today() - 14 AS created_at,
            123 AS user_id
        UNION ALL
        SELECT
            today() - 20 AS created_at,
            456 AS user_id
    )
    ARRAY JOIN range(30) AS n
)
WHERE created_at <= today()
GROUP BY created_at
FORMAT TSV

2019-04-11  1
2019-04-12  1
2019-04-13  1
2019-04-14  1
2019-04-15  1
2019-04-16  1
2019-04-17  2
2019-04-18  2
2019-04-19  2
2019-04-20  2
2019-04-21  2
2019-04-22  2
2019-04-23  2
2019-04-24  2
2019-04-25  2
2019-04-26  2
2019-04-27  2
2019-04-28  2
2019-04-29  2
2019-04-30  2
2019-05-01  2

21 rows in set. Elapsed: 0.005 sec.

您还可以创建视图或临时文件 table。