• LeetCode——Rank Scores


    Write a SQL query to rank scores. If there is a tie between two scores, both should have the same ranking. Note that after a tie, the next ranking number should be the next consecutive integer value. In other words, there should be no "holes" between ranks.
    
    +----+-------+
    | Id | Score |
    +----+-------+
    | 1  | 3.50  |
    | 2  | 3.65  |
    | 3  | 4.00  |
    | 4  | 3.85  |
    | 5  | 4.00  |
    | 6  | 3.65  |
    +----+-------+
    For example, given the above Scores table, your query should generate the following report (order by highest score):
    
    +-------+------+
    | Score | Rank |
    +-------+------+
    | 4.00  | 1    |
    | 4.00  | 1    |
    | 3.85  | 2    |
    | 3.65  | 3    |
    | 3.65  | 3    |
    | 3.50  | 4    |
    +-------+------+
    

    此题,其本质就是赋值行号(需要注意分数相同的情景).

    在实践过程中,初版答案如下所示:

    # Write your MySQL query statement below
    SELECT 
        a.Score AS Score,
        (SELECT COUNT(DISTINCT b.Score) FROM Scores b where b.Score >= a.Score) AS Rank
    FROM Scores a ORDER BY a.Score DESC;
    

    此处,使用select count来统计行号,注意使用distinct来区分相同分数.
    但是,此解题方案的效率较差,sql运行肯定是越快越好.
    因此,在sql中引入变量来赋值行号,以替代耗时的select count操作.

    # Write your MySQL query statement below
    SELECT 
        Score,
        @row := @row + (@pre <> (@pre := Score)) AS Rank
    FROM Scores, (SELECT @row := 0, @pre := -1) t
    ORDER BY Score DESC;
    

    此处,查询是在Scores与临时表之间进行cross join.
    此外,使用临时变量(@row,@pre)记录行号.
    Tips:

    • 通过@pre与当前Score的比较,确定是否+1,需要注意mysql中的true/false0/1);
    • sql中,set/update语句中,=表示赋值;在set/update/select中,:=表示赋值,因此使用:=.

    通过以上改进,mysql的运行效率得到了较大的提高.

    PS:
    如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!
    程序员打怪之路

  • 相关阅读:
    几个计算广告学的课程
    Jie Bao 牛人cv
    如果英剧《黑镜子》拍第三季,你来写一集剧本策划,你想写一个什么样的故事呢? 知乎
    设计模式之迭代器与组合模式
    javascript 时钟clock
    项目中的需求蔓延
    一个产生随机random markers 例子
    设计模式之模板方法模式
    设计模式之反(向)模式
    转:用函数式编程技术编写优美的 JavaScript
  • 原文地址:https://www.cnblogs.com/jason1990/p/11641041.html
Copyright © 2020-2023  润新知