MySQL equivalent of ORACLES rank()

前端 未结 2 1519
一向
一向 2020-12-01 20:19

Oracle has 2 functions - rank() and dense_rank() - which i\'ve found very useful for some applications. I am doing something in mysql now and was wondering if they have some

相关标签:
2条回答
  • 2020-12-01 20:31

    how about this "dense_rank implement" in MySQL

    CREATE TABLE `person` (  
     `id` int(11) DEFAULT NULL,  
     `first_name` varchar(20) DEFAULT NULL,  
     `age` int(11) DEFAULT NULL,  
     `gender` char(1) DEFAULT NULL);
    
    INSERT INTO `person` VALUES 
    (1,'Bob',25,'M'),
    (2,'Jane',20,'F'),
    (3,'Jack',30,'M'),
    (4,'Bill',32,'M'),
    (5,'Nick',22,'M'),
    (6,'Kathy',18,'F'),
    (7,'Steve',36,'M'),
    (8,'Anne',25,'F'),
    (9,'Mike',25,'M');
    

    the data before dense_rank() like this

    mysql> select * from person;
    +------+------------+------+--------+
    | id   | first_name | age  | gender |
    +------+------------+------+--------+
    |    1 | Bob        |   25 | M      |
    |    2 | Jane       |   20 | F      |
    |    3 | Jack       |   30 | M      |
    |    4 | Bill       |   32 | M      |
    |    5 | Nick       |   22 | M      |
    |    6 | Kathy      |   18 | F      |
    |    7 | Steve      |   36 | M      |
    |    8 | Anne       |   25 | F      |
    |    9 | Mike       |   25 | M      |
    +------+------------+------+--------+
    9 rows in set (0.00 sec)
    

    the data after dense_rank() like this,including "partition by" function

    +------------+--------+------+------+
    | first_name | gender | age  | rank |
    +------------+--------+------+------+
    | Anne       | F      |   25 |    1 |
    | Jane       | F      |   20 |    2 |
    | Kathy      | F      |   18 |    3 |
    | Steve      | M      |   36 |    1 |
    | Bill       | M      |   32 |    2 |
    | Jack       | M      |   30 |    3 |
    | Mike       | M      |   25 |    4 |
    | Bob        | M      |   25 |    4 |
    | Nick       | M      |   22 |    6 |
    +------------+--------+------+------+
    9 rows in set (0.00 sec)
    

    the query statement is

    select first_name,t1.gender,age,FIND_IN_SET(age,t1.age_set) as rank from person t2,
    (select gender,group_concat(age order by age desc) as age_set from person group by gender) t1
    where t1.gender=t2.gender
    order by t1.gender,rank
    
    0 讨论(0)
  • 2020-12-01 20:47

    Nothing directly equivalent, but you can fake it with some (not terribly efficient) self-joins. Some sample code from a collection of MySQL query howtos:

    SELECT v1.name, v1.votes, COUNT(v2.votes) AS Rank
    FROM votes v1
    JOIN votes v2 ON v1.votes < v2.votes OR (v1.votes=v2.votes and v1.name = v2.name)
    GROUP BY v1.name, v1.votes
    ORDER BY v1.votes DESC, v1.name DESC;
    +-------+-------+------+
    | name  | votes | Rank |
    +-------+-------+------+
    | Green |    50 |    1 |
    | Black |    40 |    2 |
    | White |    20 |    3 |
    | Brown |    20 |    3 |
    | Jones |    15 |    5 |
    | Smith |    10 |    6 |
    +-------+-------+------+ 
    
    0 讨论(0)
提交回复
热议问题