这条 SQL 如何解释?

2018-10-11 13:10:40 +08:00
 skyworker
如下:

SELECT * FROM users WHERE id = (SELECT floor(RAND() * (SELECT MAX(id) FROM users)))

看起来是获取一条随机的 user 数据, 但是真实运行后, 会发现有时候获取 1 条数据; 有时候为空; 有时候会获取 2 条数据. 超出了我对 SQL 运行机制的理解...
4774 次点击
所在节点    MySQL
31 条回复
yesterdaysun
2018-10-11 13:45:49 +08:00
刚看到 kenorizon 说的, 我觉得有道理, 应该是因为这个是非相关子查询, 但是因为里面含有 rand(), 所以这个子查询不会像普通的一样只跑一遍, 而是每一行都跑了, 所以实际查询的是所有记录里刚好可以和随机出来的那个 id 相等的记录, 所以条数不等, 而且数据量少估计难重现
kenorizon
2018-10-11 13:46:20 +08:00
@kenorizon #20 这一层的请无视吧,刚刚测试次数太少 没测全= =
pabupa
2018-10-11 13:48:36 +08:00
我这里也是,,测试数据库只有 40 条数据。。。
lichao
2018-10-11 13:49:15 +08:00
@yesterdaysun 貌似是的,所以拆分成两条语句可以规避。。
pabupa
2018-10-11 13:51:54 +08:00
@lichao #12 应该是 mysql 多次计算随机数了,,这样是可以的。
kevin2ex
2018-10-11 13:53:03 +08:00
改成这样,没有发现多条数据。
SELECT b.id, a.* FROM users a, (SELECT floor(RAND() * (SELECT MAX(id) FROM users)) as id ) b WHERE a.id = b.id;
will0404
2018-10-11 13:59:50 +08:00
> "RAND() in a WHERE clause is evaluated for every row (when selecting from one table) or combination of rows (when selecting from a multiple-table join). Thus, for optimizer purposes, RAND() is not a constant value and cannot be used for index optimizations"

See: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_rand
mossss21
2018-10-11 14:08:07 +08:00
每行都做了一次 RAND(),理论上查询结果最多会有 COUNT(id)条,最少 0 条
chenqimiao
2018-10-11 16:35:53 +08:00
神奇
winsky
2018-10-11 23:05:52 +08:00
这么神奇,国庆前我身边刚好也有人遇到过这个问题。
也可以看看这个 https://bugs.mysql.com/bug.php?id=86624
liuxey
2018-10-12 08:29:25 +08:00
#12 + #28 结合起来就解释了楼主的疑问

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/496669

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX