写点什么

MySQL 没有 RowNum,那我该怎么按“行”查询或删除数据?

  • 2021 年 11 月 11 日
  • 本文字数:2446 字

    阅读完需:约 8 分钟

在日常开发中,不知道你是否遇到过查询条件为 “行” 的时候呢?其实,是有很多场景会使用到的。



比如前段时间,我们业务中有一张应用信息表,这张表是同事小刘直接用 csv 文件导入的,会有其他公司的人对这些数据进行人工分析,导入时并没有设置自增主键,小刘没有想到已经给自己留下了隐患。


这张表有 20w 行数据,其中第 8w 条 - 15w 条是多余的,也不能重新导,因为可能其他公司的同事已经在处理了,这时该怎么删除多余数据呢?


为了不被领导邀请爬山,他找到我求救。


小刘:“哈哥,救命救命,这 MySQL 没有自增主键,我咋删除第[8w,15w]的数据啊?”


陈哈哈:“啊?MySQL 又没有 rowNum,那咋搞啊?我不会,不会~”



小刘:“一顿串儿!哈哥快来”


陈哈哈:“哎呀,我这活儿急得一匹,下午再说吧。”



小刘:“今儿晚上,望京小腰,不请我是你儿子!”


陈哈哈:“什么串儿串儿的,都是兄弟,说的就跟我怕你吹牛 B 不请似的,来吧来吧,一起看看咋处理。”


小刘:“……”


其实,在 MySQL 中确实没有 rownum 伪列,但我们可以自己写函数定义。线上数据不方便,下面我拿一些测试数据来举例吧(15 条),如下


mysql> select * from t_student;


+------------+-----+-----+-------+----------+-----------+


| NAME | SEX | AGE | CLASS | GRADE | HOBBY |


+------------+-----+-----+-------+----------+-----------+


| 陈哈哈 | 男 | 15 | 18 班 | 9 年级 1 | 上网 |


| 扈亚鹏 | 男 | 15 | 18 班 | 9 年级 1 | 美食 |


| 徐立楠 | 女 | 14 | 18 班 | 9 年级 1 | 阅读 |


| 陈子凝 | 女 | 15 | 18 班 | 9 年级 1 | 看电影 |


| 刘晓莉 | 女 | 14 | 18 班 | 9 年级 1 | 金希澈 |


| 陈哈哈 1 | 男 | 15 | 18 班 | 9 年级 2 | 上网


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


  |
复制代码


| 扈亚鹏 1 | 男 | 15 | 18 班 | 9 年级 2 | 美食 |


| 徐立楠 1 | 女 | 14 | 18 班 | 9 年级 2 | 阅读 |


| 陈子凝 1 | 女 | 15 | 18 班 | 9 年级 2 | 看电影 |


| 刘晓莉 1 | 女 | 14 | 18 班 | 9 年级 1 | 金希澈 |


| 陈哈哈 2 | 男 | 15 | 18 班 | 9 年级 2 | 上网 |


| 扈亚鹏 2 | 男 | 15 | 18 班 | 9 年级 2 | 美食 |


| 徐立楠 2 | 女 | 14 | 18 班 | 9 年级 2 | 阅读 |


| 陈子凝 2 | 女 | 15 | 18 班 | 9 年级 2 | 看电影 |


| 刘晓莉 2 | 女 | 14 | 18 班 | 9 年级 1 | 金希澈 |


+------------+-----+-----+-------+----------+-----------+


15 rows in set (0.00 sec)


如何查询这些的数据的行值呢?SQL 如下:


-- 在没自增主键情况下,查询数据行(rownum),行号


select @rownum:=@rownum+1 AS rownum,NAME,SEX,CLASS,GRADE


from t_student ,(SELECT @rownum:=0) r;


查询结果如下:


mysql> select @rownum:=@rownum+1 AS rownum,NAME,SEX,CLASS,GRADE from t_student ,(SELECT @rownum:=0) r;


+--------+------------+-----+-------+----------+


| rownum | NAME | SEX | CLASS | GRADE |


+--------+------------+-----+-------+----------+


| 1 | 陈哈哈 | 男 | 18 班 | 9 年级 1 |


| 2 | 扈亚鹏 | 男 | 18 班 | 9 年级 1 |


| 3 | 徐立楠 | 女 | 18 班 | 9 年级 1 |


| 4 | 陈子凝 | 女 | 18 班 | 9 年级 1 |


| 5 | 刘晓莉 | 女 | 18 班 | 9 年级 1 |


| 6 | 陈哈哈 1 | 男 | 18 班 | 9 年级 2 |


| 7 | 扈亚鹏 1 | 男 | 18 班 | 9 年级 2 |


| 8 | 徐立楠 1 | 女 | 18 班 | 9 年级 2 |


| 9 | 陈子凝 1 | 女 | 18 班 | 9 年级 2 |


| 10 | 刘晓莉 1 | 女 | 18 班 | 9 年级 1 |


| 11 | 陈哈哈 2 | 男 | 18 班 | 9 年级 2 |


| 12 | 扈亚鹏 2 | 男 | 18 班 | 9 年级 2 |


| 13 | 徐立楠 2 | 女 | 18 班 | 9 年级 2 |


| 14 | 陈子凝 2 | 女 | 18 班 | 9 年级 2 |


| 15 | 刘晓莉 2 | 女 | 18 班 | 9 年级 1 |


+--------+------------+-----+-------+----------+


15 rows in set (0.00 sec)


可以看到查询到的行号,那我该怎么通过上面查到的 rownum 行来进行删除呢?其实这个想法是行不通的,因为上面的 rownum 就是一个展示值,是没有其他实际效果的。



但是,我可以通过找到表中的唯一列(如 UUID、MD5、包名、身份证 ID),通过范围条件查询 rownum,从而找到需要删除的唯一键集合,比如在这张表中存在唯一键是“NAME”,那么我通过查到第[6,10]行数据的唯一键“NAME”,从而通过子查询来删除,(这里是把人名后有“1”的删除)。SQL 如下:


我们先看一下第[6,10]行数据,SQL 如下:


-- 查询第 6 到第 10 行数据。


SELECT * from (select @rownum:=@rownum+1 AS rownum,NAME,SEX,CLASS,GRADE from


t_student ,(SELECT @rownum:=0) r) t where t.rownum between 6?and 10;


返回结果:


mysql> SELECT * from (select @rownum:=@rownum+1 AS rownum,NAME,SEX,CLASS,GRADE from t_student ,(SELECT @rownum:=0) r) t


-> where t.rownum between 6 and 10;


+--------+------------+-----+-------+----------+


| rownum | NAME | SEX | CLASS | GRADE |


+--------+------------+-----+-------+----------+


| 6 | 陈哈哈 1 | 男 | 18 班 | 9 年级 2 |


| 7 | 扈亚鹏 1 | 男 | 18 班 | 9 年级 2 |


| 8 | 徐立楠 1 | 女 | 18 班 | 9 年级 2 |


| 9 | 陈子凝 1 | 女 | 18 班 | 9 年级 2 |


| 10 | 刘晓莉 1 | 女 | 18 班 | 9 年级 1 |


+--------+------------+-----+-------+----------+


5 rows in set (0.00 sec)


下面我们来删除掉`NAME`中包含"1"的数据,也就是第 6 到第 10 行。


-- 以行为条件删除数据


DELETE from t_student where NAME in (SELECT NAME from


(select @rownum:=@rownum+1 AS rownum,NAME,SEX,CLASS,GRADE from t_student ,(SELECT @rownum:=0) r) t


where t.rownum between 6 and 10);

评论

发布
暂无评论
MySQL没有RowNum,那我该怎么按“行”查询或删除数据?