SELECT user_id,
MOD(user_id, 10) AS bucket
FROM users
LIMIT 3;
Результат:
user_id | bucket 101 | 1 105 | 5 110 | 0
SELECT MOD(order_id, 3) AS grp,
COUNT(*) AS cnt
FROM orders
GROUP BY MOD(order_id, 3)
ORDER BY grp;
Результат:
grp | cnt 0 | 412 1 | 405 2 | 400Порешать SQL-задачи в тренажёре →
Классика собеса — «разбейте пользователей на A/B-группы» или «выберите каждую N-ю запись»: ответ через остаток. Идёт в паре с FLOOR (бины) и хешированием id для детерминированного сэмплинга.
Да, MOD(x, y) и x % y вычисляют один и тот же остаток от деления; % — это инфиксный оператор, MOD — функциональная запись. В PostgreSQL и MySQL доступны обе формы, выбор чисто стилистический. В SQLite надёжнее оператор %, потому что функция mod() требует математической сборки.
В PostgreSQL, MySQL и по стандарту SQL знак результата совпадает со знаком делимого: MOD(−7, 3) = −1, а MOD(7, −3) = 1. Это не математический «неотрицательный» остаток, поэтому для гарантированно положительного результата пишут ((x % n) + n) % n. Особенно важно при бакетировании по id, где встречаются отрицательные значения.
Оператор % в SQLite есть всегда, но он работает только с целыми — оба операнда приводятся к integer. Отдельная функция mod() появилась лишь в математическом расширении SQLite 3.35 (флаг SQLITE_ENABLE_MATH_FUNCTIONS) и поддерживает дробные числа. Деление или остаток на ноль в SQLite дают NULL, а не ошибку.
COALESCE · NULLIF · CASE WHEN · STRING_AGG · COUNT · SUM OVER
Открыть SQL-тренажёр (565 задач) →