用 SQL 计算俱乐部会员人数

时间:2021-05-14 08:53:48

标签: mysql sql

编辑:根据@Strawberry 的评论,我添加了主键

目的是在任何特定日期/时间返回当前成员的数量以及过去的成员数量。

例如,假设我们有

msid  id  start                 cancelled
1     1   2020-01-01 09:00:00   null
2     2   2020-01-01 09:00:00   2020-12-31 09:00:00
3     2   2021-01-01 09:00:00   null
4     3   2020-01-01 09:00:00   2020-06-30 09:00:00
5     3   2020-02-01 09:00:00   2020-06-30 09:00:00
6     3   2020-07-01 09:00:00   null

并且我们要计算不同时间的成员数,应该返回如下

Datetime            Current  Past    <Notes - not to be returned by the query>
2020-01-01 12:00:00   3       0    -- all 3 IDs have joined earlier on this date
2020-02-01 12:00:00   3       0    -- new membership for existing member (ID 3) is not counted
2020-06-30 12:00:00   2       1    -- ID 3 has cancelled earlier on this day
2020-07-01 12:00:00   3       0    -- ID 3 has re-joined earlier on this day
2020-12-31 12:00:00   2       1    -- ID 2 has cancelled earlier on this day
2021-01-01 12:00:00   3       0    -- ID 2 has re-joined earlier on this day

一个 ID 可以是当前的或过去的,但不能同时存在。也就是说,如果过去的成员重新加入,如上述 ID 2 和 3 的情况,他们将成为当前成员,不再是过去的成员。

另外,一个会员可能有多个当前会员,但他们只能算作一个当前会员,就像上面的 ID 3 一样。

如何在 MySQL 中实现这一点?

Here is a db<>fiddle with the above data

1 个答案:

答案 0 :(得分:2)

测试一下:

WITH
cte1 AS ( SELECT start `timestamp` FROM dt
          UNION 
          SELECT cancelled FROM dt WHERE cancelled IS NOT NULL ),
cte2 AS ( SELECT DISTINCT id
          FROM dt )
SELECT cte1.`timestamp`, COUNT(DISTINCT dt.id) current, SUM(dt.id IS NULL) past
FROM cte1
CROSS JOIN cte2
LEFT JOIN dt ON cte1.`timestamp` >= dt.start
            AND (cte1.`timestamp` < dt.cancelled OR dt.cancelled IS NULL)
            AND cte2.id = dt.id
GROUP BY cte1.`timestamp`

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=942e4c97951ed0929e178134ef67ce69

相关问题