You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL技术问询:如何查询每个赛季进球最多的球队?

解决每个赛季进球最多球队的SQL查询问题

嘿,作为SQL新手,遇到JOIN和分组排序的问题太正常了,我来一步步帮你搞定这个需求!

先分析你原SQL的问题

你的语句有几个关键问题导致无法运行:

  • 子查询里用的是id_team,但外层查询写的是team_id,字段名不匹配,会直接报错
  • 没有按season分组,你要的是每个赛季的top球队,原语句只按球队分组,没法区分赛季
  • 没有关联team_table获取球队名称,也没处理“每个赛季取最大值”的核心逻辑

正确的查询思路

我们需要分两步走:

  1. 先把所有球队的进球数据按赛季+球队汇总(包含主场和客场的进球)
  2. 找出每个赛季的最大进球数,再匹配到对应的球队;或者用窗口函数直接给每个赛季的球队排名,取第一名

方法1:先汇总,再匹配赛季最大值

-- 第一步:汇总每个赛季每个球队的总进球
WITH team_season_goals AS (
    SELECT
        mt.season,
        tt.team_name,
        SUM(
            CASE
                WHEN mt.home_team_id = tt.id_team THEN mt.home_team_goal
                ELSE mt.away_team_goal
            END
        ) AS total_goals
    FROM match_table mt
    -- 关联球队表,这里用INNER JOIN就够(因为比赛里的球队肯定在球队表中)
    JOIN team_table tt ON tt.id_team IN (mt.home_team_id, mt.away_team_id)
    GROUP BY mt.season, tt.id_team, tt.team_name
),
-- 第二步:找出每个赛季的最大进球数
season_max_goals AS (
    SELECT season, MAX(total_goals) AS max_goals
    FROM team_season_goals
    GROUP BY season
)
-- 第三步:匹配得到每个赛季进球最多的球队
SELECT
    tsg.season,
    tsg.team_name,
    tsg.total_goals
FROM team_season_goals tsg
JOIN season_max_goals smg 
    ON tsg.season = smg.season 
    AND tsg.total_goals = smg.max_goals
ORDER BY tsg.season;

方法2:用窗口函数(更简洁,推荐)

窗口函数ROW_NUMBER()可以帮我们按赛季分组,给每个球队的进球数排名,直接取排名第一的:

WITH team_season_goals AS (
    SELECT
        mt.season,
        tt.team_name,
        SUM(
            CASE
                WHEN mt.home_team_id = tt.id_team THEN mt.home_team_goal
                ELSE mt.away_team_goal
            END
        ) AS total_goals,
        -- 按赛季分组,按进球数降序排名
        ROW_NUMBER() OVER (PARTITION BY mt.season ORDER BY SUM(
            CASE
                WHEN mt.home_team_id = tt.id_team THEN mt.home_team_goal
                ELSE mt.away_team_goal
            END
        ) DESC) AS rank_num
    FROM match_table mt
    JOIN team_table tt ON tt.id_team IN (mt.home_team_id, mt.away_team_id)
    GROUP BY mt.season, tt.id_team, tt.team_name
)
-- 取每个赛季排名第一的球队
SELECT season, team_name, total_goals
FROM team_season_goals
WHERE rank_num = 1
ORDER BY season;

关于JOIN类型的小解释

  • INNER JOIN:只返回两个表中匹配成功的数据,这里因为match_table里的球队ID肯定都在team_table里,所以用这个最适合,不会出现多余的NULL数据
  • LEFT JOIN:返回左表(这里是match_table)的所有数据,右表(team_table)匹配不到的会显示NULL,如果你的数据里可能存在球队表没有的ID,可以用这个,但一般比赛数据不会有这种情况
  • RIGHT/FULL JOIN:这里完全用不上,RIGHT JOIN是返回右表所有数据,FULL是返回两个表所有数据,都不符合我们的需求

运行结果(对应你的示例数据)

seasonteam_nametotal_goals
2008/2009C3
2009/2010B2
2011/2012E1
2012/2013B2
2012/2013E2

(注:2012/2013赛季B和E都进了2球,所以会返回两个结果,如果要只返回一个,可以把ROW_NUMBER()换成RANK()或者DENSE_RANK(),根据需求调整)

内容的提问来源于stack exchange,提问作者yoyo_24

火山引擎 最新活动