SQL同时用orderby和limit查询的坑

【今日推荐】:为什么一到面试就懵逼!>>> hot3.png

  • 目录
  • 1. 前言
  • 2. 重演案例
  • 2.1 mysql数据表结构
  • 2.2 问题排查
  • 2.2.1出问题的SQL查询
  • 2.2.2优化后的SQL查询
  • 3. 探讨分析和总结

1. 前言

前几天公司某项目读取的全部数据条数是13条,分页limit是10,但是显示出来的数据却只有11条,也就是说丢失了两条数据,那这是什么原因导致的呢?刚开始,这个问题让我百思不解,后来上百度求解答的时候,看到了一个和我遇到类似问题的博主发的一篇文章,顿时心花路放,感觉自己经验不够,为了防止忘记,在这里记录一下下.

首先给出参考博文地址,以示尊重:

https://blog.csdn.net/tsxw24/article/details/44994835

2. 重演案例

2.1 mysql数据表结构

CREATE TABLE `NewTable` (

`id`  int(11) NOT NULL AUTO_INCREMENT COMMENT '部门id' ,

`partnerid`  int(11) NOT NULL COMMENT '线下合作商ID' ,

`department_name`  varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '部门名称' ,

`addremark`  varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '无备注' COMMENT '添加部门备注' ,

`del`  tinyint(1) NOT NULL DEFAULT 1 COMMENT '关闭部门 默认1 关闭2' ,

`delremark`  varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '无备注' COMMENT '关闭部门备注' ,

`sort_num`  int(11) NOT NULL DEFAULT 0 COMMENT '排序 数字越越靠前' ,

PRIMARY KEY (`id`)

)

ENGINE=InnoDB

DEFAULT CHARACTER SET=utf8mb4 COLLATE=utf8mb4_general_ci

COMMENT='线下合作-部门(子公司)'

AUTO_INCREMENT=1

ROW_FORMAT=COMPACT

;

2.2 问题排查

2.2.1出问题的SQL查询

$sql = "

SELECT

p1.`id`,p1.`department_name`,p1.`del` AS delStatus,p1.sort_num

FROM

`t_partner_department` AS p1

WHERE {$where}

ORDER BY p1.`sort_num` DESC

LIMIT {$limits}

";

可以看到上面的SQL语句是根据字段sort_num来排序的,但我们添加部门信息的时候是不会设置排序值的,默认为0,所以当使用上述SQL语句查询,由于SQL排序值大多为0,而在排序相等的情况下,oeder by排序的顺序是随机的,而不是固定的,于是出现了数据丢失问题。

2.2.2优化后的SQL查询

$sql = "

SELECT

p1.`id`,p1.`department_name`,p1.`del` AS delStatus,p1.sort_num

FROM `t_partner_department` AS p1

WHERE {$where}

ORDER BY p1.`sort_num` DESC ,p1.`id` ASC

LIMIT {$limits}";

可以看到上面SQL语句的oeder by排序除了根据sort_num降序,还根据id进行升序,如果sort_num排序值相同,那么则以id排序值为准;反之,如果sort_num排序值不同,则先按照sort_num排序,然后再把sort_num排序值相同的按照id排序。

3. 探讨分析和总结

通过排查,如果SQL查询不使用了order by和limit,输出的数据是完整的,但是一旦使用它们来做数据分页显示并排序,如果order by的排序值大多相等,则会造成顺序的不确定,因为在排序值相同的情况下,order by排序的顺序是随机的而不是固定的;因此,我们可以通过增加排序条件让其排序结果是确定的、唯一的,这样就能够使得排序固定,而不出现数据丢失的问题。

你可能感兴趣的:(SQL同时用orderby和limit查询的坑)