首页 > 解决方案 > MySQL - 如何确定按两列排序并允许平局的表的位置排名?

问题描述

我有一个表格(锦标赛),其中包含球队列表及其累积积分和净胜球(进球数 - 失球数)。

比赛

+-----------+--------+-----------+
|   team    | points | goal_diff |
+-----------+--------+-----------+
| USA       |      7 |   -2      |
| Brazil    |     12 |   +7      |
| Argentina |     12 |   +10     |
| Germany   |      7 |   -2      |
| Italy     |      3 |    0      |
+-----------+--------+-----------+

我如何按积分对他们进行排名,然后按净胜球排名保持相同排名并跳过随后的排名位置?我正在寻找产生这个最终结果的查询:

+-----------+--------+-----------+------+
|   team    | points | goal_diff | rank |
+-----------+--------+-----------+------+
| Argentina |     12 | +10       |    1 |
| Brazil    |     12 | +7        |    2 |
| USA       |      7 | -2        |    3 |
| Germany   |      7 | -2        |    3 |
| Italy     |      3 | 0         |    5 |
+-----------+--------+-----------+------+

我已经能够通过积分列对它们进行排名并保持相同的关系,但不知道如何包含第二列条件

SELECT s.team, s.points, s.goal_diff,
    (( SELECT COUNT(DISTINCT points) FROM Tournament WHERE points > s.points ) + 1) AS rank
FROM Tournament s
ORDER BY s.points DESC

谢谢您的帮助!

标签: mysql

解决方案


我错过了:在#1 中(@rank 之后),这就是为什么显示 blob 和 null 值的原因

SELECT
    a.team,
    a.points,
    a.goal_diff,
    a.rank 
FROM
    (
    SELECT
        t.team,
        t.points,
        t.goal_diff,
    IF
        ( @points = t.points, 
        IF 
            (@goal_diff = t.goal_diff, @rank, @rank :=@inRank),
        @rank := @inRank ) AS rank,                               # 2
        @inRank := @inRank + 1,                                   # 3
        @points := t.points,                                      # 4
        @goal_diff := t.goal_diff  
    FROM
        `tournament` t,
        ( SELECT @points := NULL, @goal_diff := NULL, @rank := 0, @inRank := 1 ) b  # 1
    ORDER BY
    t.points DESC, t.goal_diff DESC
    ) a

解释:

@用于声明变量。:=表示为变量赋值。#1 sql 实际上是一个变量初始值。

@points :  a custom declared variable for storing the points value in last row
@rank   :  a custom declared variable for storing regular condition rank number  
@inRank :  a custom declared variable for storing a count of row

mysql 中的if(boolean, trueResult, falseResult)函数有点像三元运算。在#2 中,如果初始变量@points 等于选择的值,它将显示@Rank 的值现在为0。此 if() 函数用于判断点值是否相同。

在 if() 函数之后,我们分配 #3 和 #4 中的变量。

sql #3 在每一行中增加,这个变量将计算行号。因此,当分数不同时,我可以得到排名。我认为将@inRank 重命名为@increaseRank 会更好。

sql #4 将此行的点值分配给变量。我们用它来计算下一行的积分值。


推荐阅读