You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改SQL查询以计算2021-2022常规赛每位球员最近5场比赛的每28分钟平均数据

如何修改SQL查询以计算2021-2022常规赛每位球员最近5场比赛的每28分钟平均数据

嘿,我完全理解你现在的困扰——既要精准拿到每个球员2021-2022常规赛的最近5场比赛,又要正确算出每28分钟的平均数据,之前的查询确实在这两个点上踩了坑。咱们一步步把它修正过来:

核心问题分析

你之前的两个版本都有明显的问题:

  • 第一个查询没有限定赛季范围,也没筛选每个球员的最近5场,HAVING AVG(MIN) >=28只是过滤了平均每场上场28分钟以上的球员,但不是针对最近5场的统计。
  • 第二个查询用GROUP BY game_date再加LIMIT 5,只返回了5行数据,而不是每个球员的5场比赛。

修正后的完整查询

我们用窗口函数来标记每个球员的最近5场比赛,再用正确的逻辑计算每28分钟的数据:

-- 第一步:先筛选出2021-2022常规赛中每个球员的最近5场比赛
WITH player_last_5_games AS (
    SELECT 
        PLAYER_ID,
        PLAYER_NAME,
        FGM,
        FGA,
        FG3M,
        FG3A,
        FTM,
        FTA,
        OREB,
        DREB,
        REB,
        AST,
        TOV,
        STL,
        BLK,
        BLKA,
        PF,
        PFD,
        PTS,
        PLUS_MINUS,
        FG_PCT,
        FG3_PCT,
        FT_PCT,
        MIN
    FROM (
        SELECT 
            *,
            -- 给每个球员的比赛按日期倒序排名,最近的比赛排第1
            ROW_NUMBER() OVER (PARTITION BY PLAYER_ID ORDER BY game_date DESC) AS game_rank
        FROM sis_basketball_research.nba_player_game_logs
        -- 务必筛选2021-2022常规赛,根据表实际字段调整(如果没有season字段,可用game_date范围替代)
        WHERE season = '2021-2022' AND game_type = 'Regular Season'
    ) ranked_games
    -- 只保留每个球员的前5场(最近的5场)
    WHERE game_rank <= 5
)
-- 第二步:计算每28分钟的平均数据
SELECT 
    PLAYER_ID,
    PLAYER_NAME,
    -- 关键逻辑:总数据 / 总上场分钟数 * 28,这是NBA标准的每N分钟换算方式
    -- 用NULLIF避免出现除以0的错误(比如球员5场都没上场的极端情况)
    SUM(FGM) / NULLIF(SUM(MIN), 0) * 28 AS FGM_per_28min,
    SUM(FGA) / NULLIF(SUM(MIN), 0) * 28 AS FGA_per_28min,
    SUM(FG3M) / NULLIF(SUM(MIN), 0) * 28 AS FG3M_per_28min,
    SUM(FG3A) / NULLIF(SUM(MIN), 0) * 28 AS FG3A_per_28min,
    SUM(FTM) / NULLIF(SUM(MIN), 0) * 28 AS FTM_per_28min,
    SUM(FTA) / NULLIF(SUM(MIN), 0) * 28 AS FTA_per_28min,
    SUM(OREB) / NULLIF(SUM(MIN), 0) * 28 AS OREB_per_28min,
    SUM(DREB) / NULLIF(SUM(MIN), 0) * 28 AS DREB_per_28min,
    SUM(REB) / NULLIF(SUM(MIN), 0) * 28 AS REB_per_28min,
    SUM(AST) / NULLIF(SUM(MIN), 0) * 28 AS AST_per_28min,
    SUM(TOV) / NULLIF(SUM(MIN), 0) * 28 AS TOV_per_28min,
    SUM(STL) / NULLIF(SUM(MIN), 0) * 28 AS STL_per_28min,
    SUM(BLK) / NULLIF(SUM(MIN), 0) * 28 AS BLK_per_28min,
    SUM(BLKA) / NULLIF(SUM(MIN), 0) * 28 AS BLKA_per_28min,
    SUM(PF) / NULLIF(SUM(MIN), 0) * 28 AS PF_per_28min,
    SUM(PFD) / NULLIF(SUM(MIN), 0) * 28 AS PFD_per_28min,
    SUM(PTS) / NULLIF(SUM(MIN), 0) * 28 AS PTS_per_28min,
    SUM(PLUS_MINUS) / NULLIF(SUM(MIN), 0) * 28 AS PLUS_MINUS_per_28min,
    -- 命中率直接取平均即可,因为单场命中率是比例值,平均更能反映整体表现
    AVG(FG_PCT) AS FG_PCT_avg,
    AVG(FG3_PCT) AS FG3_PCT_avg,
    AVG(FT_PCT) AS FT_PCT_avg
FROM player_last_5_games
GROUP BY PLAYER_ID, PLAYER_NAME
-- 可选:如果要过滤掉总上场时间为0的球员,加上这个条件
HAVING SUM(MIN) > 0;

关键细节说明

  1. 窗口函数ROW_NUMBER():通过PARTITION BY PLAYER_ID确保每个球员的比赛单独排序,ORDER BY game_date DESC让最近的比赛排在最前面,然后取game_rank <=5就得到了每个球员的最近5场,完美解决了之前LIMIT 5的问题。
  2. 赛季筛选:一定要加WHERE条件限定2021-2022常规赛,不然会混入其他赛季或季后赛的数据,结果就不准确了。如果你的表没有season或game_type字段,可以用game_date范围替代,比如game_date BETWEEN '2021-10-19' AND '2022-04-10'(这是2021-2022常规赛的实际起止日期)。
  3. 每28分钟换算逻辑:用总数据除以总上场分钟数再乘以28,这是NBA官方常用的统计方式,比单场换算后再平均更准确,因为它反映了球员在这段时间内的总产出效率。NULLIF(SUM(MIN),0)是为了防止出现除以0的错误,避免查询报错。
  4. 命中率处理:命中率是单场的投篮比例,直接取平均就能反映球员在这5场的整体命中率表现,不需要换算成每28分钟的数值。

备注:内容来源于stack exchange,提问作者Pete Curaro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 12:44:33