Нужно найти пользователей, у которых последний заказ был оплачен.
Есть таблица:
orders
id | user_id | status | created_at
1 | 10 | paid | 2026-01-01
2 | 10 | cancelled | 2026-01-05
3 | 20 | paid | 2026-01-03
4 | 30 | failed | 2026-01-02
Кто-то пишет так:
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY created_at DESC
) AS rn
FROM orders
WHERE status = 'paid'
)
SELECT *
FROM ranked
WHERE rn = 1;
На вид логично. Но запрос неверный.
Подвох: фильтр
WHERE status = 'paid' срабатывает до ROW_NUMBER().То есть SQL сначала выбрасывает все неоплаченные заказы, а потом ищет последний среди оставшихся оплаченных.
Пользователь
10 попадёт в результат, хотя его реальный последний заказ — cancelled.Правильно так:
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY created_at DESC, id DESC
) AS rn
FROM orders
)
SELECT *
FROM ranked
WHERE rn = 1
AND status = 'paid';
Сначала находим последний заказ вообще, и только потом проверяем его статус.
Вот почему порядок фильтрации в SQL может полностью менять смысл запроса.