我有一个桌子(锦标赛),其中包含一个球队列表及其积分和目标差异(进球得分 - 失球)。
比赛
+-----------+--------+-----------+
| 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
谢谢您的帮助!
对于任何想要解决这个问题的人,我最终将我的数据库升级到MariaDB 10.3.14并使用了RANK()函数,它完全符合我的需要。
这是代码:
SELECT team, points, goal_diff,
RANK() OVER (
ORDER BY
points DESC,
goal_diff DESC
) rank
FROM Tournament;
我知道升级数据库可能不是每个人的选择,但在我的情况下这是一个非常简单的解决方案。希望它对其他人也有帮助。
我错过了:在#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实际上是一个变量initial。
@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将此行的points值赋给变量。我们用它来与下一行的分值进行比较。
所以,基本上,这是来自@ wl.GIG答案的次要编辑。运行@ wl.GIG时得到的结果如下;
+-------------+----------+-------------+--------+
| team | points | goal_diff | rank |
+-------------+----------+-------------+--------+
| Brazil | 12 | 7 | 1 |
| Argentina | 12 | 10 | 1 |
| USA | 7 | -2 | 3 |
| Germany | 7 | -2 | 3 |
| Italy | 3 | 0 | 5 |
+-------------+----------+-------------+--------+
它没有给出OP所需的正确等级,但这是一个非常好的方法,我对它非常感兴趣。所以,我已经根据OP的要求进行了可以返回排名的测试,这是我提出的:
SELECT
a.team,
a.points,
a.goal_diff,
a.rank
FROM (SELECT
t.team,
t.points,
t.points+t.goal_diff AS tp, -- I've added this.
t.goal_diff,
IF
(@points = t.points+t.goal_diff, --- changed this part.
@rank, @rank := @inRank) AS rank,
@inRank := @inRank + 1,
@Points := t.points+t.goal_diff --- and changed this part.
FROM
`tournament` t,
( SELECT @points := NULL, @rank = 0, @inRank := 1 ) b
ORDER BY t.points DESC,t.goal_diff DESC
-- and added another condition in the ordering
) a;
正如你所看到的,这不是一个很大的编辑,但我用这个,我得到如下结果:
+-------------+----------+-------------+--------+
| 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 |
+-------------+----------+-------------+--------+
而已。