MySQL查询以获取特定排名

3

我有一个关于MySQL数据库的查询,以这种方式工作,我得到了这个结果:

> Rank  Gold    Silver  Bronze  Total 
> 1     76      78      77      231 
> 2     4       5       6       15 
> 3     4       1       1       6
> 4     3       0       0       3 
> 5     2       1       1       4 
> 5     2       1       1       4
> 6     2       0       0       2
> 7     1       1       1       3
> 8     1       1       0       2
> 9     1       0       2       3
> 9     1       0       2       3
> 9     1       0       2       3
> 10    0       1       0       1

我的这个结果是从以下查询中获得的(我隐藏了主要的查询以免写太多代码):

select
    CASE
        WHEN (@Gold=T.Gold and @Silver=T.Silver and @Bronze=T.Bronze) THEN @rownum ELSE @rownum:=@rownum+1 end as Rank,        

        (@Gold:=T.Gold) Gold,
        (@Silver:=T.Silver) Silver,
        (@Bronze:=T.Bronze) Bronze,
        T.Total

from

(MAIN_QUERY) T,

(SELECT @rownum:=0) r, 
    (SELECT @Gold:=0) g,
    (SELECT @Silver:=0) s,
    (SELECT @Bronze:=0) b

   order by Gold desc, Silver DESC, Bronze DESC

但是与其得到上面的结果,我希望调整Rank列(和我的查询),根据之前重复的行逐渐增加它,即:

> Rank  Gold    Silver  Bronze  Total 
    > 1     76      78      77      231 
    > 2     4       5       6       15 
    > 3     4       1       1       6
    > 4     3       0       0       3 
    > 5     2       1       1       4 
    > 5     2       1       1       4
    > 7     2       0       0       2
    > 8     1       1       1       3
    > 9     1       1       0       2
    > 10    1       0       2       3
    > 10    1       0       2       3
    > 10    1       0       2       3
    > 13    0       1       0       1

等等。

你能帮我得到这个结果吗?


以上示例中排名6怎么样?这个预期排名的标准是什么? - Hanky Panky
如果是我,我会为国家、颜色和数量分别设置一列,并从那里开始。 - Strawberry
@hankypanky 这就是重点。操作者希望以体育比分板的方式处理平局。 - Strawberry
但是真正的计分牌会跳过整个排名吗?有两个团队并列第5名是可以的,但是没有团队在第6名上,然后从第7名继续是否也可以接受? - Hanky Panky
1
你可以引入另一个变量作为群组计数器。如果没有人回答,请提醒我。 - Drew
显示剩余3条评论
1个回答

2
也许另一个变量可以实现这个功能:
SELECT @rownum := @rownum + 1, 
       CASE 
         WHEN ( @gold = T.gold 
                AND @silver = T.silver 
                AND @bronze = T.bronze ) THEN @rank := @rank 
         ELSE @rank := @rownum 
       END                     AS Rank, 
       ( @gold := T.gold )     Gold, 
       ( @silver := T.silver ) Silver, 
       ( @bronze := T.bronze ) Bronze, 
       T.total 
FROM   (MAIN_QUERY) T 
       CROSS JOIN (SELECT @rownum := 0, 
                          @gold := 0, 
                          @silver := 0, 
                          @bronze := 0, 
                          @rank := 0) v 
ORDER  BY gold DESC, 
          silver DESC, 
          bronze DESC 

这里有一个演示

注意:如果您的数据的所有列都为0,则此方法将不起作用。


MySQL手册明确指出,选择列的计算顺序不能保证。因此,这不是一种安全的策略。请参见此处。在fiddle中使其正常工作是一回事,但我永远不会将其部署到生产环境中。 - Drew
@Drew 嗯,对。如果主查询中有 order by 呢? - Blank
我创建了上面的标签来存放一些我重新发现的东西。mysql-variables。只有我们中的少数人以安全的方式编写答案。Baron的必读文章博客中,他使用greatest()方法来确保安全性。可以使用least()greatest()coalesce()或一系列看起来毫无意义但实际上有其方法的if语句来清理事物。 - Drew
但是它们很耗时间。因此,一个人的生物节律和运势必须在此时此刻投入其中。此外,问题必须设置得很好。 - Drew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接