Mysql 而不是按兰德订购

Mysql 而不是按兰德订购,mysql,sql,random,sql-order-by,Mysql,Sql,Random,Sql Order By,我使用这个查询: SELECT f.id FROM articles f JOIN ( SELECT RAND() * (SELECT MAX(id) FROM articles) AS max_id ) AS m WHERE f.id >= m.max_id ORDER BY f.id ASC LIMIT 5 问题是它返回了意外的行数。它可以是1行、3行或5行。但我只需要5行。您的查询可能存在的一个问题是,它只随机选择一条记录,其余记录是连续的。如果要真正随机选择全部5个,则必须逐个选

我使用这个查询:

SELECT f.id FROM articles f
JOIN ( SELECT RAND() * (SELECT MAX(id) FROM articles) AS max_id ) AS m
WHERE f.id >= m.max_id
ORDER BY f.id ASC
LIMIT 5

问题是它返回了意外的行数。它可以是1行、3行或5行。但我只需要5行。

您的查询可能存在的一个问题是,它只随机选择一条记录,其余记录是连续的。如果要真正随机选择全部5个,则必须逐个选择:

(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random = f.id) UNION ALL
(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random = f.id) UNION ALL
(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random = f.id) UNION ALL
(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random = f.id) UNION ALL
(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random = f.id)
如果ID是连续的且没有间隙,则此操作有效。如果存在间隙,则必须将相等值更改为小于,并限制为一条记录:

(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random <= f.id LIMIT 1) UNION ALL
(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random <= f.id LIMIT 1) UNION ALL
(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random <= f.id LIMIT 1) UNION ALL
(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random <= f.id LIMIT 1) UNION ALL
(SELECT f.id FROM articles f INNER JOIN (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM articles) + 1) AS random) m ON m.random <= f.id LIMIT 1)

你的问题看起来像是重复的

根据您的表中有多少行以及您愿意接受的响应时间,您可以首先尝试经典的变体:

SELECT f.id FROM articles f
ORDER BY RAND()
LIMIT 5
如果少于一百万,这就足够了

否则,您可以应用链接文章中描述的技巧,并
UNION ALL
5个这样的查询,大致如下所示:

(SELECT r1.id
  FROM articles AS r1 JOIN
       (SELECT CEIL(RAND() *
                     (SELECT MAX(id)
                        FROM articles)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1)
 UNION ALL
 (SELECT r1.id
  FROM articles AS r1 JOIN
       (SELECT CEIL(RAND() *
                     (SELECT MAX(id)
                        FROM articles)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1)
 UNION ALL
 ... (three more queries to retrieve 5 rows)
如果您的行数很少,则此解决方案中可能存在重复。但如果行数不多,可以使用上面更简单的解决方案:)


我为第二个变体创建了一个。嗯

你想达到什么目标?选择5个随机行?选择5个连续的行(按id排序,从随机位置开始)?我想选择5个随机行您的五个连接将返回0或1行,最有可能是0,除非对
RAND
的所有五个调用都产生相同的值:)@dnswlt当然。它需要这些子查询之间的联合。我不知道查询结果如何。我想我累了,复制/粘贴了内部子查询而不是外部子查询,忘记了添加联合。谢谢你的来信。
(SELECT r1.id
  FROM articles AS r1 JOIN
       (SELECT CEIL(RAND() *
                     (SELECT MAX(id)
                        FROM articles)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1)
 UNION ALL
 (SELECT r1.id
  FROM articles AS r1 JOIN
       (SELECT CEIL(RAND() *
                     (SELECT MAX(id)
                        FROM articles)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1)
 UNION ALL
 ... (three more queries to retrieve 5 rows)