我有一个包含 100 行的表。我想从中选择 200 个项目,使用随机行生成比表中的行更多的结果:
SELECT * FROM `rows` ORDER BY RANDOM() LIMIT 200;
此查询可预测地返回 100 个结果。有没有办法随机选择表格中实际包含的内容?
编辑
join
有没有办法在不添加复合语句的情况下选择任意数量的记录?例如,如果请求LIMIT
的项目数 () 事先未知或任意大怎么办?
尝试这样的事情
SELECT *
FROM `rows`
cross join `rows`
ORDER BY RANDOM()
LIMIT 200;
您应该能够执行以下操作:
select * from rows
union all
select * from rows
order by random()
limit 200
请注意,如果您可以保证表包含 100 行,则实际上不需要 200 限制。
为union all
您提供两个副本(没有重复删除),order by
然后为您随机化该完整数据集。
当然,如果您的表包含 100 个并且您想要超过200 个,则需要添加更多的联合子句。
但是,您可能会发现简单地选择 100 行,将它们全部放入内存结构中,然后使用代码而不是 SQL 选择您想要的行更容易(也更灵活)。
这将使您可以更好地控制选择过程,当然比我们尝试为您编写的任何“SQL 体操”更重要 :-)
一种选择:
Select * From (
SELECT * FROM `rows`
UNION ALL
SELECT * FROM `rows`
) as alotofrows
ORDER BY RANDOM()
LIMIT 200;
我的方法不满足“任意大”的要求,但很容易扩展。
第一个问题是生成 N 行。在 SQLite 中,我使用了视图。您也可以考虑使用虚拟表。
CREATE VIEW V10 AS SELECT 0 AS Number UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9;
CREATE VIEW V100 AS SELECT V10.Number*10+low.Number AS Number FROM V10 JOIN V10 AS low;
CREATE VIEW V10000 AS SELECT V100.Number*100+low.Number AS Number FROM V100 JOIN V100 AS low;
查询V10000
将返回Number
0 到 9999。
现在你可以:
SELECT table.* FROM table JOIN (
SELECT (
SELECT ROWID+Number*0 AS rndid FROM table ORDER BY RANDOM()
) FROM V10000 WHERE Number<200
) ON table.ROWID=rndid;
它是如何工作的?
SELECT
从中选择一个随机行table
并返回其ROWID
,命名为rndid
;SELECT
乘以随机行;SELECT
匹配整个table
行并rndid
返回 s。如果需要超过 10000 个结果,VIEW
则可以创建另一个更宽的结果作为以前的结果。
脚注:这是一个纯 SQL(ite) 算法。使用某种编程语言,创建一个TEMP TABLE
使用重复SELECT * FROM
行可能是最有效的ORDER BY RANDOM() LIMIT 1;