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

如何在SQL联赛排名查询中添加固定位置(POS)列?

解决联赛排名中添加正确POS排名列的问题

嘿,我懂你遇到的问题了——你之前用@rownum变量得到的不是真正的联赛排名,而是分组查询时的行序号,这是因为MySQL的执行顺序搞的鬼:变量递增是在SELECT阶段执行的,而ORDER BY是最后一步才处理的,所以变量赋值的时候结果还没排序,序号自然不对。

解决方案1:基础版(按顺序生成连续排名)

核心思路是先把你的排名统计结果完全计算好并排序,再在外面套一层查询来生成排名序号。这样变量是在已经排好序的结果上递增,得到的就是正确的POS列:

SET @rownum := 0;
SELECT 
    @rownum := @rownum + 1 AS POS,
    Team,
    P,
    W,
    D,
    L,
    F,
    A,
    GD,
    Pts
FROM (
    -- 这里是你原来的统计逻辑,已经处理好分组和排序
    SELECT 
        t.tname AS Team, 
        Sum(tot.P) AS P,
        Sum(tot.W) AS W,
        Sum(tot.D) AS D,
        Sum(tot.L) AS L, 
        SUM(tot.F) as F,
        SUM(tot.A) AS A,
        SUM(tot.GD) AS GD,
        SUM(tot.Pts) AS Pts 
    FROM(
        SELECT 
            hteam Team, 
            1 P, 
            IF(hscore > ascore,1,0) W, 
            IF(hscore = ascore,1,0) D, 
            IF(hscore < ascore,1,0) L, 
            hscore F, 
            ascore A, 
            hscore-ascore GD, 
            CASE WHEN hscore > ascore THEN 3 WHEN hscore = ascore THEN 1 ELSE 0 END PTS 
        FROM games
        UNION ALL
        SELECT 
            ateam Team, 
            1 P, 
            IF(hscore < ascore,1,0) W, 
            IF(hscore = ascore,1,0) D, 
            IF(hscore > ascore,1,0) L, 
            ascore F, 
            hscore A, 
            ascore-hscore GD, 
            CASE WHEN hscore < ascore THEN 3 WHEN hscore = ascore THEN 1 ELSE 0 END PTS 
        FROM games
    ) as tot 
    JOIN teams t ON tot.Team=t.id 
    GROUP BY t.id, t.tname  -- 加上t.id更严谨,避免tname重复(虽然你设了unique,但好习惯)
    ORDER BY SUM(tot.Pts) DESC, SUM(tot.GD) DESC, SUM(tot.F) DESC
) AS ranked_teams;

解决方案2:进阶版(处理同分并列排名)

如果你的联赛规则允许同分球队并列排名(比如积分、净胜球、进球数都相同的球队排名一样),可以用多变量来追踪上一支球队的成绩,动态生成排名:

SET @prev_points := NULL;
SET @prev_gd := NULL;
SET @prev_f := NULL;
SET @rank := 0;
SET @row_num := 0;

SELECT 
    -- 对比当前球队和上一支的成绩,决定是否使用相同排名
    CASE 
        WHEN @prev_points = Pts AND @prev_gd = GD AND @prev_f = F THEN @rank
        ELSE @rank := @row_num
    END AS POS,
    Team,
    P,
    W,
    D,
    L,
    F,
    A,
    GD,
    Pts
FROM (
    -- 同样是原来的统计子查询
    SELECT 
        t.tname AS Team, 
        Sum(tot.P) AS P,
        Sum(tot.W) AS W,
        Sum(tot.D) AS D,
        Sum(tot.L) AS L, 
        SUM(tot.F) as F,
        SUM(tot.A) AS A,
        SUM(tot.GD) AS GD,
        SUM(tot.Pts) AS Pts 
    FROM(
        SELECT 
            hteam Team, 
            1 P, 
            IF(hscore > ascore,1,0) W, 
            IF(hscore = ascore,1,0) D, 
            IF(hscore < ascore,1,0) L, 
            hscore F, 
            ascore A, 
            hscore-ascore GD, 
            CASE WHEN hscore > ascore THEN 3 WHEN hscore = ascore THEN 1 ELSE 0 END PTS 
        FROM games
        UNION ALL
        SELECT 
            ateam Team, 
            1 P, 
            IF(hscore < ascore,1,0) W, 
            IF(hscore = ascore,1,0) D, 
            IF(hscore > ascore,1,0) L, 
            ascore F, 
            hscore A, 
            ascore-hscore GD, 
            CASE WHEN hscore < ascore THEN 3 WHEN hscore = ascore THEN 1 ELSE 0 END PTS 
        FROM games
    ) as tot 
    JOIN teams t ON tot.Team=t.id 
    GROUP BY t.id, t.tname
    ORDER BY SUM(tot.Pts) DESC, SUM(tot.GD) DESC, SUM(tot.F) DESC
) AS ranked_teams
-- 这里要更新变量,确保下一行能拿到当前行的成绩
CROSS JOIN (SELECT @row_num := 0, @rank := 0, @prev_points := NULL, @prev_gd := NULL, @prev_f := NULL) AS vars;

这个版本里,如果当前球队的积分、净胜球、进球数和上一支完全一致,就会和上一支共享同一个排名;如果不一样,就用当前的行号作为新的排名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:40:52