【1】明确需求:

  • 最大播放量:指某个视频在某个时刻,有多少条记录(多少用户)同时在观看它。
  • Top3:找出最大播放量最大的前三个视频。
  • 保留三位小数。

【2】解决思路整体:

因为每个播放记录有 start_timeend_time,所以:

✅ 如果某个时刻落在 start_time <= 时刻 <= end_time 之间,这条记录就算在播放中。

要找出播放量最大值,常见方法是:

  • 把每条记录的 start_time、end_time 拆成时间点。
  • 在所有时间点里,推算有多少人同时在播放。
  • 统计每个视频最大并发人数。

【3】思考 SQL 解法

可以用事件流式处理的方法来做,比如:

  1. 把每条播放记录拆成两个事件:开始播放(+1)结束播放(-1)
  2. 然后按时间排序,一步步累加正在播放的人数。
  3. 对每个视频,记录下累加人数的最大值。

【4】伪SQL步骤

假设表叫 play_record_tb

第一步:拆成两种事件(+1 / -1)

sql复制编辑SELECT 
    cid,
    start_time AS time_point,
    1 AS delta
FROM play_record_tb

UNION ALL

SELECT 
    cid,
    end_time AS time_point,
    -1 AS delta
FROM play_record_tb

这一步生成所有播放开始和结束的时间节点。

第二步:累加delta得到实时播放量

sql复制编辑WITH event_points AS (
    SELECT 
        cid,
        time_point,
        delta
    FROM (
        -- 上面的UNION子查询
    ) t
),
accumulate_counts AS (
    SELECT
        cid,
        time_point,
        SUM(delta) OVER (PARTITION BY cid ORDER BY time_point ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS current_playing
    FROM event_points
)

说明:

  • 用 SUM() OVER() 窗口函数来累计每个视频在时间序列上正在播放的人数。

第三步:取每个视频的最大播放量

sql复制编辑SELECT 
    cid,
    ROUND(MAX(current_playing), 3) AS max_play_count
FROM accumulate_counts
GROUP BY cid
ORDER BY max_play_count DESC
LIMIT 3;

【5】完整SQL总结版

sql复制编辑WITH event_points AS (
    SELECT 
        cid,
        start_time AS time_point,
        1 AS delta
    FROM play_record_tb
    UNION ALL
    SELECT 
        cid,
        end_time AS time_point,
        -1 AS delta
    FROM play_record_tb
),
accumulate_counts AS (
    SELECT
        cid,
        time_point,
        SUM(delta) OVER (PARTITION BY cid ORDER BY time_point ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS current_playing
    FROM event_points
)
SELECT 
    cid,
    ROUND(MAX(current_playing), 3) AS max_play_count
FROM accumulate_counts
GROUP BY cid
ORDER BY max_play_count DESC
LIMIT 3;

【6】解释一下结果:

  • 每个视频,找到所有时间点上正在播放的人数。
  • 取最大人数,即最大并发播放量。
  • 最后排序,取前3。