MySQL sql Rank()函数实现

本文详细介绍了MySQL SQL Rank()函数的使用方法,包括如何通过分组和排序来查找特定列的倒序第一个数据。同时,文章还讨论了在实际应用中遇到的问题,如变量缓存错误,并提供了解决方法。此外,文章分享了一个优化版的SQL查询,通过调整字段顺序和使用子查询来提高查询效率。

 MySQL sql Rank()函数实现

两列数据,以a列作为分组,查找以b列倒序的第一个。

select a,b,rownum,rank from 
    (select 
         tt.a,
         tt.b,
         @rownum:=@rownum+1 rownum,#@rownum变量加1,作为rownumber,        
         if(@temp=tt.a,@rank:=@rank+1,@rank:=1) as rank,#tt.a字段等于@temp变量,则@rank加1,否则@rank赋值为1
         @temp:=tt.a#将tt.a字段赋予@temp变量 注意该字段赋值顺序,先赋值,再自加减
        
    FROM#以下两表作关联
       (select a,b from your_table_name 
           group by a,b 
           order by a asc,b desc) tt,#一定要将同组的数据排序到一起,业务上是实际是以a作为分组,需要放前面;b业务上实际是作排序字段
       (select @rank:=0,@rownum:=0,@temp:=null) ee
    ) result
    having rank =1;

 注意 :@temp:=tt.a, 字段顺序,之前将该字段放在最后,发现问题,应该缓存出现了问题,rank列表全部为1,在该SQL执行第二次的时候rank列表才显示正常。

 

 

试试这个:

SELECT * FROM (

     SELECT * FROM posts ORDER BY dateline DESC

) GROUP BY  tid ORDER BY dateline DESC LIMIT 10  

  

 

参考:http://blog.youkuaiyun.com/ariczhou/article/details/48808417

MySQL 中,`RANK()` 是一个窗口函数,用于为结果集的行分配排名值。它通常与 `ORDER BY` 子句一起使用,以确保数据按照特定顺序排列后进行排名计算。而 `ORDER BY` 是 SQL 的标准子句,用于对查询结果进行排序,但它本身不提供排名功能。 ### RANK() 函数的使用 `RANK()` 通常作为窗口函数出现在 `SELECT` 列表中,并结合 `OVER()` 子句来定义排序规则。例如: ```sql SELECT s.*, RANK() OVER (ORDER BY sum(sc.score) DESC) AS rank_01 FROM student s LEFT JOIN sc ON s.Sid = sc.Sid GROUP BY sc.Sid; ``` 在此示例中,`RANK()` 会根据学生总成绩从高到低进行排名,并且相同成绩的学生会获得相同的排名值,后续排名会跳过相应的数字[^1]。 ### ORDER BY 的使用 `ORDER BY` 是用于对查询结果按指定列排序的子句。它可以单独使用,也可以与其他函数(如聚合函数)一起使用。例如: ```sql SELECT id, name, age FROM players ORDER BY age; ``` 此查询将返回玩家列表,并按年龄升序排列。 如果需要实现类似 `RANK()` 的效果但使用 `ORDER BY`,则需要手动维护一个排名变量。例如: ```sql SELECT pid, name, age, @curRank := @curRank + 1 AS rank FROM players p, (SELECT @curRank := 0) q ORDER BY age; ``` 在这个查询中,通过变量 `@curRank` 手动实现了一个简单的递增排名逻辑[^2]。 ### RANK() 与 ORDER BY 的区别 - **功能不同**: `RANK()` 提供了排名功能,可以处理并列排名,并根据需求决定是否跳过后续排名;而 `ORDER BY` 仅用于对结果集进行排序,不具备自动排名的能力。 - **语法结构不同**: `RANK()` 作为窗口函数必须与 `OVER()` 结合使用,而 `ORDER BY` 是独立的 SQL 子句。 - **排名逻辑不同**: 如果存在相同值,`RANK()` 会为其分配相同的排名,后续排名会跳过相应的位置(如 1, 2, 2, 4),而 `DENSE_RANK()` 则不会跳过(如 1, 2, 2, 3)。相比之下,手动实现的排名逻辑可以根据需求灵活调整。 - **性能差异**: 在大数据量情况下,使用窗口函数 `RANK()` 通常比通过变量实现的手动排名更高效,因为数据库优化器会对窗口函数进行专门优化。 ### 示例对比 #### 使用 `RANK()` 实现排名 ```sql SELECT store_name, RANK() OVER (ORDER BY store_name) AS rank_value FROM tmp_ss; ``` 此查询会根据 `store_name` 字段进行排序,并为每一行分配一个排名值,如果有重复值,则它们会共享相同的排名[^3]。 #### 使用 `ORDER BY` 和变量实现排名 ```sql SELECT store_name, @rank := @rank + 1 AS row_number, @val := store_name FROM tmp_ss, (SELECT @val := '', @rank := 0) t1 ORDER BY store_name; ``` 该查询利用变量 `@rank` 来模拟 `ROW_NUMBER()` 的行为,每行都会获得唯一的排名值,即使有重复值也不会共享排名。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值