我有一个表格(锦标赛),其中包含球队及其累积积分和净胜球(进球数 - 失球数)的列表。
比赛
+-----------+--------+-----------+
| 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 实际上是一个变量首字母。
@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 将此行的点值分配给变量。我们用它来露营下一行的点值。
所以,基本上,这是@wl的一个小编辑。吉格回答。我在@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 |
+-------------+----------+-------------+--------+
就是这样。