Коротка відповідь
middleSELECT u.id, c.* FROM users u JOIN (SELECT user_id, comment_text, created_at, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY created_at DESC) rn FROM comments) c ON u.id = c.user_id WHERE c.rn <= 3;
Повне пояснення
Що це і навіщо Запит повертає останні три коментарі для кожного користувача. Це корисно при відображенні «активності» у профілі чи в панелі адміністратора.
Ключові принципи
ROW_NUMBER()– вікно, що нумерує рядки у кожній групіuser_id.PARTITION BY user_id ORDER BY created_at DESC– сортування за датою спадково.- Фільтр
WHERE rn <= 3обмежує результат трьома останніми.
Як працює
- Підзапит створює тимчасову таблицю з усіма коментарями, додаючи поле
rn. - Головний запит з’єднує цю таблицю з
usersза ключемid = user_id. - Фільтр повертає лише рядки, де
rn≤ 3.
Практика й реалізація
SELECT u.id, c.comment_text, c.created_at
FROM users u
JOIN (
SELECT user_id, comment_text, created_at,
ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY created_at DESC) rn
FROM comments
) c ON u.id = c.user_id
WHERE c.rn <= 3;
У PostgreSQL, MySQL 8+, SQLite 3.25+ підтримують ROW_NUMBER().
Тестування
- У Jest можна перевірити, що результат містить максимум 3 рядки на користувача.
- При використанні Prisma:
await prisma.comment.findMany({ where:{ userId }, orderBy:{ createdAt:'desc' }, take:3 }).
Оптимізація запитів
- Індекси
comments(user_id, created_at DESC)підвищують швидкість сортування. EXPLAINпоказує, що використовується індексний скан.
Безпека
- Підтримка параметризованих запитів (prepared statements) запобігає SQL‑ін’єкціям.
- Перевірка прав доступу: лише власник або адміністратор може бачити коментарі.
Підсумок Запит ефективно обмежує кількість рядків за допомогою віконної функції, що робить його простим у підтримці та масштабованим для великих таблиць.