Условие
Таблица RequestAccepted(requester_id, accepter_id, accept_date) — принятые заявки в друзья. Дружба симметрична (если A принял заявку от B — оба становятся друзьями друг друга один раз).
Верните id, num — пользователя с наибольшим числом друзей и количество. Гарантируется единственный максимум.
Решение
Идея — UNION ALL обеих сторон, потом GROUP BY
WITH friends AS (
SELECT requester_id AS id FROM RequestAccepted
UNION ALL
SELECT accepter_id AS id FROM RequestAccepted
)
SELECT id, COUNT(*) AS num
FROM friends
GROUP BY id
ORDER BY num DESC
LIMIT 1;Почему именно UNION ALL
UNION (без ALL) удаляет дубли — два независимых запроса схлопнутся, и пользователь, у которого 3 друга, будет посчитан один раз. Это ошибка.
UNION ALL сохраняет все строки — каждая дружба даёт +1 к обоим участникам.
Альтернатива через подсчёт по обеим колонкам
SELECT id, SUM(cnt) AS num
FROM (
SELECT requester_id AS id, COUNT(*) AS cnt FROM RequestAccepted GROUP BY requester_id
UNION ALL
SELECT accepter_id AS id, COUNT(*) AS cnt FROM RequestAccepted GROUP BY accepter_id
) t
GROUP BY id
ORDER BY num DESC
LIMIT 1;Логика та же, но через предварительную группировку.
Подводные камни
UNIONвместоUNION ALL. Один из самых частых багов SQL-собесов.- Двойной счёт. В таблице каждая пара уже без дублей, но если кто-то «подружился» дважды (хоть это и невозможно по бизнесу), задвоится. На реальных данных проверяйте.
- Тай-брейк. Если бы максимум был не уникален —
LIMIT 1дал бы случайный, нужно было бы возвращать все черезDENSE_RANK() = 1.
Эталонный ответ
UNION ALL двух колонок (requester и accepter) → GROUP BY id → ORDER BY COUNT(*) DESC LIMIT 1. Никогда не UNION без ALL.