Собесов

LeetCode SQL — Friend Requests II: пользователь с максимумом друзей

SQLUNION ALL и группировкаСредняяJunior

Условие

Таблица 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;

Логика та же, но через предварительную группировку.

Подводные камни

  1. UNION вместо UNION ALL. Один из самых частых багов SQL-собесов.
  2. Двойной счёт. В таблице каждая пара уже без дублей, но если кто-то «подружился» дважды (хоть это и невозможно по бизнесу), задвоится. На реальных данных проверяйте.
  3. Тай-брейк. Если бы максимум был не уникален — LIMIT 1 дал бы случайный, нужно было бы возвращать все через DENSE_RANK() = 1.

Эталонный ответ

UNION ALL двух колонок (requester и accepter) → GROUP BY idORDER BY COUNT(*) DESC LIMIT 1. Никогда не UNION без ALL.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти