My approach does not satisfy the "arbitrarily large" requirements, but it scales easily.
The first problem is to generate N lines. In SQLite, I used views. You may also consider using virtual tables.
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;
Request V10000 will return Number from 0 to 9999.
Now you can:
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;
How it works?
- In most internal
SELECT select one random row from table and return its ROWID named rndid ; - An intermediate
SELECT multiplies random strings; - Outer
SELECT matches integer table rows with rndid return.
If more than 10,000 results are required, another older VIEW can be created as the previous one.
Footnote: This is a pure SQL (ite) algorithm. Using some programming language, probably the most efficient would be to create a TEMP TABLE using repeating lines SELECT * FROM ORDER BY RANDOM() LIMIT 1;
source share