思路:

第一步: 按照时间 at_time 升序,进来的 加一,离开的减一;

代码如下:

SELECT artical_id, in_time as at_time, 1 as uv FROM tb_user_log
        UNION ALL
        SELECT artical_id, out_time as at_time, -1 as uv FROM tb_user_log
        ORDER BY at_time

结果如下:

+------------+---------------------+----+
| artical_id | at_time             | uv |
+------------+---------------------+----+
|       9001 | 2021-11-01 10:00:00 |  1 |
|       9001 | 2021-11-01 10:00:01 |  1 |
|       9001 | 2021-11-01 10:00:09 |  1 |
|       9001 | 2021-11-01 10:00:11 | -1 |
|       9001 | 2021-11-01 10:00:28 |  1 |
|       9001 | 2021-11-01 10:00:38 | -1 |
|       9001 | 2021-11-01 10:00:51 |  1 |
|       9001 | 2021-11-01 10:00:58 | -1 |
|       9001 | 2021-11-01 10:00:59 | -1 |
|       9001 | 2021-11-01 10:01:50 | -1 |
|       9002 | 2021-11-01 11:00:45 |  1 |
|       9002 | 2021-11-01 11:00:55 |  1 |
|       9002 | 2021-11-01 11:01:11 | -1 |
|       9002 | 2021-11-01 11:01:24 | -1 |
+------------+---------------------+----+

第二步: 利用窗口函数相加,统计出当前最大观看人数

SELECT artical_id, at_time,
        SUM(uv) over(PARTITION BY artical_id ORDER BY at_time, uv DESC) as current_max
    FROM (
        SELECT artical_id, in_time as at_time, 1 as uv FROM tb_user_log
        UNION ALL
        SELECT artical_id, out_time as at_time, -1 as uv FROM tb_user_log
        ORDER BY at_time
    ) as t_uv_at_time
    WHERE artical_id != 0
+------------+---------------------+-------------+
| artical_id | at_time             | current_max |
+------------+---------------------+-------------+
|       9001 | 2021-11-01 10:00:00 |           1 |
|       9001 | 2021-11-01 10:00:01 |           2 |
|       9001 | 2021-11-01 10:00:09 |           3 |
|       9001 | 2021-11-01 10:00:11 |           2 |
|       9001 | 2021-11-01 10:00:28 |           3 |
|       9001 | 2021-11-01 10:00:38 |           2 |
|       9001 | 2021-11-01 10:00:51 |           3 |
|       9001 | 2021-11-01 10:00:58 |           2 |
|       9001 | 2021-11-01 10:00:59 |           1 |
|       9001 | 2021-11-01 10:01:50 |           0 |
|       9002 | 2021-11-01 11:00:45 |           1 |
|       9002 | 2021-11-01 11:00:55 |           2 |
|       9002 | 2021-11-01 11:01:11 |           1 |
|       9002 | 2021-11-01 11:01:24 |           0 |
+------------+---------------------+-------------+

第三步:取最大值

SELECT artical_id, MAX(current_max) as max_uv
FROM (
    SELECT artical_id, at_time,
        SUM(uv) over(PARTITION BY artical_id ORDER BY at_time, uv DESC) as current_max
    FROM (
        SELECT artical_id, in_time as at_time, 1 as uv FROM tb_user_log
        UNION ALL
        SELECT artical_id, out_time as at_time, -1 as uv FROM tb_user_log
        ORDER BY at_time
    ) as t_uv_at_time
    WHERE artical_id != 0
) as t_artical_cur_max
GROUP BY artical_id
ORDER BY max_uv DESC;

结果如下:

+------------+--------+
| artical_id | max_uv |
+------------+--------+
|       9001 |      3 |
|       9002 |      2 |
+------------+--------+