mysql 以自增id等于某个random()函数算出的值为条件查出两条数据
SELECT
id
FROM
users
WHERE
id = FLOOR(
rand() * (
(SELECT max(id) FROM users) - (SELECT min(id) FROM users)
) + (SELECT min(id) FROM users)
);
这是你写的SQL,我用手边的表查得时候不仅有两个结果的,还有空的,还有三个结果的.我也有点费解了.这种谜一样的问题是怎么出现的??

创建了一个单列表.一共1000条数据.

下面我们来复现问题

可以看到问题就出现在了这里,id=floor(rand()*1000)在我们的直观印象中,应该等于一个值.然而实际上不是这样,
在这里,floor(rand()*1000)是在变化的
也就是说,这1000行数据,执行这条语句的时候,是这样的操作:
- 判断第一行的id 1是否等于
floor(rand()*1000), - 判断第二行的id 2是否等于
floor(rand()*1000), - 判断第三行的id 3是否等于
floor(rand()*1000),
我们只看这三次操作就够了,后边的floor(rand()*1000)是在不断变化的,第一次操作也许等于2,第2次操作可能等于1,第三次操作可能等于3.写成代码的话就是这样.
function rand() {
// 随机生成一个数N
return N
}
for (let i = 1; i <= 1000; i++) {
if (i == rand()) {
//选中这一条记录
//可以看到,每次匹配的时候,都会执行一次rand()
}
}
//而我们想要的其实是
let selected = rand()
for (let i = 1; i <= 1000; i++) {
if (i == selected) {
//选中这一条记录
//每次都和已选出且不会变动的随机值进行比较
}
}
在mariadb的文档中也提到,In a WHERE clause, RAND() is evaluated each time the WHERE is executed.
这就造成了id看似是在和一个值比较,实际上是1000个id分别和1000个随机数进行比较,两个数刚好相等的概率是1*1/1000,而刚好比较一千次,所以每次查到的结果期望值为1(个),但是这并不是稳定的,所以才会出现有时候查不到,有时候查到两条三条这中情况.
解决问题
知道了问题发生的原因,解决的思路自然就出现了,让rand()只计算一次.
第一个方法,使用join
SELECT
`测试表`.`id`
FROM
`测试表`
INNER JOIN (
SELECT
floor(rand() *(MAX(id) - MIN(id))) + min(id) AS id
FROM
`测试表`
) AS tmp
WHERE
`测试表`.`id` = `tmp`.`id`;
第二个方法,使用会话变量.
SET @rnd = RAND();
SELECT
id
FROM
`测试表`
WHERE
id = (
SELECT
floor(@rnd * (MAX(id) - MIN(id))) + min(id)
FROM
`测试表`
);
引用自:
https://segmentfault.com/q/1010000016824164?utm_source=tag-newest
https://stackoverflow.com/questions/47503471/mysql-where-rand-behaviour
https://stackoverflow.com/questions/49342846/strange-behavior-or-rand-in-mariadb-single-rand-delivers-more-than-1-result
mysql 以自增id等于某个random()函数算出的值为条件查出两条数据的更多相关文章
- mysql 数据库自增id 的总结
有一个表StuInfo,里面只有两列 StuID,StuName其中StuID是int型,主键,自增列.现在我要插入数据,让他自动的向上增长,insert into StuInfo(StuID,Stu ...
- MYSQL获取自增ID的四种方法
MYSQL获取自增ID的四种方法 1. select max(id) from tablename 2.SELECT LAST_INSERT_ID() 函数 LAST_INSERT_ID 是与tabl ...
- MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)
测试缘由 一个开发同事做了一个框架,里面主键是uuid,我跟他建议说mysql不要用uuid用自增主键,自增主键效率高,他说不一定高,我说innodb的索引特性导致了自增id做主键是效率最好的,为了拿 ...
- mysql数据库自增id重新从1排序的两种方法
mysql默认自增ID是从1开始了,但当我们如果有插入表或使用delete删除id之后ID就会不会从1开始了哦. 使用mysql时,通常表中会有一个自增的id字段,但当我们想将表中的数据清空重新添 ...
- DBS-MySQL:MYSQL获取自增ID的四种方法
ylbtech-DBS-MySQL:MYSQL获取自增ID的四种方法 1.返回顶部 1. 1. select max(id) from tablename 2.SELECT LAST_INSERT_I ...
- mysql数据库表自增ID批量清零 AUTO_INCREMENT = 0
mysql数据库表自增ID批量清零 AUTO_INCREMENT = 0 #将数据库表自增ID批量清零 SELECT CONCAT( 'ALTER TABLE ', TABLE_NAME, ' AUT ...
- mysql 数据库查询最后两条数据
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u011925175/article/details/24186917 有一个mysql数据库的 ...
- 【sql】mysql数据库做两条数据替换的操作,不使用第三方变量
需求: 1.将数据库中两条数据中的唯一约束列 做值的替换 原始思想: 将两条数据查出来,在程序中设置第三方变量,进行两条数据的替换,然后将原始两条数据删除,将新的两条替换后的数据插入. 新思想: 1 ...
- 为什么数据库能查出两条id相同的数据
sql如下: SELECT t.*,d.name as "workName" FROM t_traceability_slice t LEFT JOIN sys_departmen ...
- mysql 返回自增id
String dateNow= DateTime.Now.ToString("yyyyMMddhhmmss"+ new Random().Next(1, 99)); //随机数 ...
随机推荐
- 方法综合练习:out、params、ref
using System; namespace ConsoleApp1 { class Program { /// <summary> /// 求两个参数之间的最大值 /// </s ...
- python实现图片转PDF
import os from PIL import Image from reportlab.pdfgen import canvas def image_resize(img, width, hei ...
- holiday12
holiday12--linux basis super user(root) In linux, account root usually use for system maintain and m ...
- Kubernetes--管理Pod对象的容器(1)
Pod是Kubernetes系统的基础单元,是资源对象模型中可由用户创建或部署的最小组件,也是在Kubernetes系统上运行容器化应用的资源对象.其他的大多数资源对象都是用于支撑和扩展Pod对象功能 ...
- Redis API存取
RedisClient redisClient = new RedisClient("127.0.0.1", 6379); [HttpGet] public int RedisIn ...
- Jmeter添加Plugins Manager插件管理器后增加常用base类函数
路径为/lib/ext/jmeter-plugins-manager-1.7.jar 放置即可打开插件管理器: 搜索Custom JMeter Functions后自动下载安装即可:
- 独显坏掉,openSUSE启动黑屏卡死
我的Dell Vostro 1440配置双显卡,独显是 AMD 的.可能是因为散热的问题,独显烧坏了.原先每次启动都有 openSUSE 的圆形启动动画,显卡烧坏后,启动动画变成三个点. 装 Debi ...
- Calendar设定月份时要注意日期
先看下代码 public static void main(String[] args) { int dataMonth = 4; DateFormat dateFormat = new Simple ...
- edge 浏览器部分功能
模拟打印情况的调试
- 第17章 使用日志记录监视和排除错误(ASP.NET Core in Action, 2nd Edition)
第3部分 扩展应用程序 我们在第1部分和第2部分中介绍了大量内容:我们查看了您将用于构建传统服务器渲染的 Razor Pages 应用程序以及 Web API 的所有主要功能组件.在第3部分中,我们将 ...