Query

Select a random sample of rows

3 min · updated September 2, 2026

The portable way to grab a random handful of rows — works everywhere, but sorts every row in the table to do it:

-- PostgreSQL, DuckDB
SELECT * FROM products ORDER BY random() LIMIT 20;

-- MySQL, BigQuery
SELECT * FROM products ORDER BY RAND() LIMIT 20;

-- SQLite
SELECT * FROM products ORDER BY RANDOM() LIMIT 20;

For a large table, most warehouses and PostgreSQL offer real sampling clauses that skip most of the data instead of sorting all of it:

-- Snowflake  (SAMPLE / TABLESAMPLE are interchangeable keywords)
SELECT * FROM products SAMPLE (20 ROWS);
SELECT * FROM products SAMPLE (1);            -- ~1% of rows, BERNOULLI-style by default

-- BigQuery
SELECT * FROM products TABLESAMPLE SYSTEM (10 PERCENT);

-- DuckDB
SELECT * FROM products USING SAMPLE 20;
SELECT * FROM products USING SAMPLE 1%;

-- PostgreSQL
SELECT * FROM products TABLESAMPLE BERNOULLI (1);  -- ~1% of rows, scans every row (slower, more random)
SELECT * FROM products TABLESAMPLE SYSTEM (1);      -- ~1% of rows, whole-page sampling (faster, clumpier)

ORDER BY RANDOM()/RAND() LIMIT n sorts the whole table — it assigns every row a random sort key and fully sorts them just to keep a handful. Fine for a small table; a full scan-and-sort for a large one. Snowflake, BigQuery, DuckDB and PostgreSQL all have a dedicated sampling clause that reads a random subset of storage blocks instead of touching every row — much faster, at the cost of an approximate (not exact) row count. MySQL and SQLite have no table-sampling clause at all, so ORDER BY RAND()/RANDOM() LIMIT n (or sampling on an indexed random column you maintain yourself) is the only built-in option there.

← All recipes