【mysql 】mysql 获取排列序号

在进入正题之前先来了解一个mysql中的小知识点:

①   := 与 = 的区别

:=   赋值的意思。在set update select 中表示赋值的意思,用的比较少一般都用=,但是在用变量实现行号时(比如本文标题获取排列序号),一定要用:=。

=   等于的意思,只有当set 和 update时,和:=的意思是一样的,表示赋值,其余情况都是等于的意思。

② 用户变量 @

@rank 是对一个叫rank的参数进行赋值。对用户变量赋值有两种方式,一种直接用"="另一种用":="。其区别在于使用set命令对用户变量赋值时,两种方式都可以使用;当使用select语句对用户变量进行赋值时,只能使用“:=”方式,因为在select语句中,“=”被看做是比较操作符。

好了,现在进入正题。

1、根据某字段按序排列并获取排序号。

先写一个小例子:

SELECT a.*,@rank:[email protected] + 1 AS rank_no
FROM (
SELECT *
FROM `logs`
WHERE log_created> "2017-09-01"
ORDER BY count DESC
     ) a, (SELECT @rank:= 0) b
这个sql的作用是将日志创建时间在2017.09.01之前的日志按访问量进行倒序排序,并返回序号。(当访问量相同的时候,按正常顺序,继续排序)。

运行结果如下:

select @rank:= 0 或者 set @rank=0;
这句话其实就是将rank赋值0,从零开始加1编号,上面两种写法都可以。

用set的那种方法我也列出来一下,

set @rank= 0;
SELECT a.log_id,a.log_created,a.count,@rank:[email protected] + 1 AS rank_no
FROM (
SELECT *
FROM `logs`
WHERE log_update > "2017-09-01"
ORDER BY count DESC
) a;
所以,获取排序序号还是很简单的,基本上都是固定的方式,里面一层select是正常的sql排序的语句,外面一层是对查到的已排好序的数据列进行rank自增的操作,所以一开始@rank:=0。

其中需要注意的一点是,当排名相同时,想让序号也一样该怎么办,比如上面的查询结果id为1707101100和1711131423的访问次数都是3,上面的sql是将他们按序继续编号的,要是想编号相同可以这样解决:

2、根据某字段按序排列获取排序号,且当该字段的值存在多个相同的记录时,则相同值排序号相同。

SET @rank = 0 ,@rowtotal := NULL;
SELECT
a.log_id, a.log_created, a.count,
CASE
WHEN @rowtotal = a.count THEN
@rank
WHEN @rowtotal := a.count THEN
@rank := @rank + 1
END AS rank_no
FROM
(
SELECT *
FROM `logs`
WHERE log_update > "2017-09-01"
ORDER BY count DESC
) a
运行结果:

从上面的sql语句可以看出多了一句case函数,(rowtotal表示count)根据情况对rank进行赋值,当rowtotal等于count时,序号就是rank,当rowtotal正常赋值时,言下之意就是不等于,但是又不能用!= ,(其实这样说也不准确,我也不知道该怎么表达,有知道的人博友可以帮忙补充一下~~~),这样就实现了相同记录编号相同的目的,同时其余记录继续编号。

3、根据某字段按序排列获取排序号,且当该字段的值存在多个相同的记录时,则相同值的记录的排序号相同,并且下一组值的排序号为上一组内记录数+上一个排序号。

同样先看代码:

SET @rank = 0 ,@rowtotal := NULL ,@rowtotal1 = NULL ,@sart := 0;
SELECT a.log_id, a.log_created, a.count,
CASE
WHEN @rowtotal = a.count THEN @rank
WHEN @rowtotal := a.count THEN @rank := @rank + 1 + @sart
END AS rank_no,
CASE
WHEN @rowtotal1 = a.count THEN @sart := @sart + 1
WHEN @rowtotal1 := a.count THEN @sart := 0
END AS sart
FROM
(
SELECT *
FROM `logs`
WHERE log_update > "2017-09-01"
ORDER BY count DESC
) a

运行结果:

上面的sql里又增加了一个参数sart,表示当前每次相同的个数,(同时还增加了rowtotal1,用于区别之前的roetotal,因为在这段sql中rowtotal在运行期间已被多次赋值,不适合做sart的比较参数)下一组记录,将在之前的排名上加上此参数就表示,下一组记录的排序编码。为了再次验证sql准确性,再看一组运行结果,(调整日志创建时间为log_update > "2016-06-20" and log_update < "2017-03-01"),

好了,这三种常用的获取排列序号的sql写好了,供大家参考一下,若是有不正确的地方还望大家指出,互相学习。

2018/04/19错误纠正:

上面的sql有个问题就是当数据是0的时候,没有进行特殊处理这个时候得到的rank_no是一个null值,排序就会出问题,下面针对第三种情况做一下纠正其余的类似:

SET @rank = 0 ,@rowtotal := NULL ,@rowtotal1 = NULL ,@sart := 0;
SELECT a.log_id, a.log_created, a.count,
CASE
WHEN @rowtotal = a.count THEN @rank
WHEN @rowtotal := a.count THEN @rank := @rank + 1 + @sart
WHEN @rowtotal = 0 THEN @rank := @rank +1 [email protected]
END AS rank_no,
CASE
WHEN @rowtotal1 = a.count THEN @sart := @sart + 1
WHEN @rowtotal1 := a.count THEN @sart := 0
WHEN @rowtotal1 =0 THEN @sart := 0
END AS sart
FROM
(
SELECT *
FROM `logs`
WHERE log_update > "2017-09-01"
ORDER BY count DESC
) a
上面的黑体字就是修正后的处理sql。
————————————————
版权声明:本文为CSDN博主「crainnogao」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/gao763024185/article/details/79638052

原文地址:https://www.cnblogs.com/yucongblog/p/12111142.html

时间: 2024-10-27 09:02:21

【mysql 】mysql 获取排列序号的相关文章

MySQL数据库获取多个汉字拼音的首字母函数

需求简介:最近的一个项目,想实现如下图所示的显示效果.很明显,如果能够获取对应的汉字词组中每个汉字的拼音首字母就可以实现了,如果是固定的几组汉字,人为的拼一下就可以 了,不过项目中有多处功能需要这个效果,并且事先也不知道对应的汉字是什么,所以就需要一个函数来完成这件事情了,根据网上查询的资料自己改进了一个 函数实现的效果,现分享如下. 1:阅读建议      如果你还没有看过我上一篇博文——MySQL数据库获取汉字拼音的首字母函数,强烈建议请先看一下,因为本篇博文是在她的基础之上写的,相关雷同的

mysql高效获取两张表共同字段的交集数据

问题: 例如下面两站表A,B.A表和B表分别有5-10w数据.A表结构如下:id bid name title publisher extraB表结构如下id bid name title publisher A出版社也为很多人出版了书籍,B出版社也为很多人出版了书籍,有sql语句找出这两个出版社为那些人 共同出版书籍,用innerjoin太慢,有没有什么更好的办法? 解答一: 由于不知道你表的索引情况,至于用join还是in和exists不太好说,理论上讲,exists最快.in次之.join

Mysql ID重新排列

我们经常会遇到,在删除数据库某条记录时,原来的ID排序会有间隔,比如删除了ID为8的数据,这个表的ID排序就会从7直接到9, 那我们如何解决这个ID重新排列的问题呢? 只需一下三步: 1.删除这个表的ID ALTER TABLE `table_name` DROP `id`; 2.重新建立ID字段 ALTER TABLE `table_name` ADD `id` MEDIUMINT( 8 ) NOT NULL FIRST; 3.为这个字段设置新的主键,并且自动增长 ALTER TABLE `t

mysql记录集中记录序号,MySQL中实现rownum功能类似的语句(转)

MySQL 如何实现 Oracle 的 ROWNUM mysql> SELECT * FROM frutas;+-----------+----------+| nombre    | color    |+-----------+----------+| fresa     | rojo     || platano   | amarillo || manzana   | verde    || uva       | verde    || pera      | verde    || m

sqlserver、mysql如何获取连接字符串

sqlserver.mysql如何获取连接字符串 步骤: 一.新建文本文档xxx.txt,修改文件类型为.udl 二.打开该文件,在<提供数据>中找到对应的服务. 三.在连接中选择需要的数据库,并填写相关信息. 四.测试连接,若成功则跳至下一步,失败则是用户信息有误,重新修改. 五.把xxx.udl后缀名改为txt,打开就可以找到连接字符串. 注:这里找到的连接字符串中有provider,可能不支持,如不支持,请改为server sqlserver.mysql如何获取连接字符串

mysql sql获取上条插入id,update影响行数

1.获取上条插入数据 LAST_INSERT_ID(); 2.获取update影响行数. ROW_COUNT(); mysql> UPDATE t -> SET address = 'beijing111' -> WHERE id = 1 -> AND NAME = 'yubowei'; Query OK, 1 row affected (0.30 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> mysql> SEL

[MySQL] MySQL的自动化安装部署

有过MySQL运维的人应该都清楚,线上的MySQL一般都采用源码编译,因为这样才可以根据企业的各自需要选择要编译的功能,虽然MySQL的源码编译挺简单的,但是试想一下,如果你有几百台服务器同时要安装MySQL,难道你还一台台去手动编译.编写配置文件吗?这显然太低效了,本文讨论MySQL的自动化安装部署. 1.制作符合自己需求的RPM包 我们要根据MySQL的源码编译符合企业需求的RPM包,源码获取命令如下: wget http://downloads.mysql.com/archives/get

ERROR 2002 (HY000): Can&#39;t connect to local MySQL server through socket &#39;/var/lib/mysql/mysql.sock&#39; (2)

当使用host参数为"localhost"连接Mysql服务时,会优先使用"sock文件"进行连接,而不是使用"IP:端口"进行连接,而Mysql尝试使用"sock文件"进行连接时,却无法获取"sock文件"的位置. 要解决此错误,解决方法: 将连接参数"host"的值由"localhost"改成"127.0.0.1": ERROR 2002 (H

[MySQL] MySQL的自己主动化安装部署

有过MySQL运维的人应该都清楚,线上的MySQL一般都採用源代码编译,由于这样才干够依据企业的各自须要选择要编译的功能,尽管MySQL的源代码编译挺简单的,可是试想一下,假设你有几百台server同一时候要安装MySQL,难道你还一台台去手动编译.编写配置文件吗?这显然太低效了,本文讨论MySQL的自己主动化安装部署. 1.制作符合自己需求的RPM包 我们要依据MySQL的源代码编译符合企业需求的RPM包,源代码获取命令例如以下: wget http://downloads.mysql.com