Skip to content

Instantly share code, notes, and snippets.

@brainwire
Last active August 29, 2015 14:09
Show Gist options
  • Select an option

  • Save brainwire/9523d70f966e2e856b8b to your computer and use it in GitHub Desktop.

Select an option

Save brainwire/9523d70f966e2e856b8b to your computer and use it in GitHub Desktop.
Postgres. Выборка N случайных записей
{table} — название таблицы;
{pk} — имя PrimaryKey-поля;
{fields} — список полей для выборки (можно указать и "*");
{exclude} — условие (набор условий) для исключения записей из выборки. Например «t.id NOT IN (1,2,3,4)»;
{limit} — количество записей в финальной выборке
WITH RECURSIVE r AS (
WITH b AS (
SELECT
min(t.{pk}),
(
SELECT t.{pk}
FROM {table} AS t
WHERE {exclude} t.is_active
ORDER BY t.{pk} DESC
LIMIT 1
OFFSET {limit} - 1
) max
FROM {table} AS t WHERE {exclude} t.is_active
)
(
SELECT
t.{pk}, min, max, array[]::integer[] || t.{pk} AS a, 0 AS n
FROM {table} AS t, b
WHERE
t.{pk} >= min + ((max - min) * random())::int AND
{exclude}
t.is_active
LIMIT 1
) UNION ALL (
SELECT t.{pk}, min, max, a || t.{pk}, r.n + 1 AS n
FROM {table} AS t, r
WHERE
t.{pk} >= min + ((max - min) * random())::int AND
t.{pk} <> all(a) AND
r.n + 1 < {limit} AND
{exclude}
t.is_active
LIMIT 1
)
)
SELECT {fields} FROM {table} AS t, r WHERE r.{pk} = t.{pk}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment