Как найти самую популярную фамилию среди актеров в SQL
При работе с базами данных часто возникает задача выявить наиболее часто встречающееся значение в столбце. В контексте таблицы actor из базы Sakila (или аналогичной) требуется определить фамилию, которая встречается у максимального числа актеров. Рассмотрим, как составить эффективный SQL-запрос для получения такого результата.
Базовая задача: группировка и сортировка
Исходное условие: необходимо вывести две колонки - last_name (фамилия) и count (количество актеров с такой фамилией). Результат должен содержать только одну запись - фамилию с наибольшим числом актеров.
Простое решение с LIMIT
Наиболее прямолинейный подход - сгруппировать записи по фамилии, подсчитать количество вхождений, отсортировать по убыванию и ограничить вывод одной строкой:
SELECT last_name, COUNT(*) AS count
FROM actor
GROUP BY last_name
ORDER BY count DESC
LIMIT 1;Этот запрос работает корректно, но имеет потенциальный недостаток: если несколько фамилий имеют одинаковое максимальное количество актеров, будет показана только одна из них (зависит от порядка сортировки).
Более оптимальный подход: подзапрос с агрегацией
Чтобы гарантированно получить все фамилии с максимальным числом актеров, можно использовать вложенный запрос, который сначала находит максимальное значение count, а затем выбирает все фамилии с этим значением:
SELECT last_name, COUNT(*) AS count
FROM actor
GROUP BY last_name
HAVING COUNT(*) = (
SELECT MAX(cnt) FROM (
SELECT COUNT(*) AS cnt
FROM actor
GROUP BY last_name
) AS sub
);Такой запрос возвращает все фамилии, у которых количество актеров равно максимальному. Это особенно полезно, когда в базе несколько фамилий-лидеров.
Использование оконных функций (для PostgreSQL, MySQL 8+)
В современных СУБД можно применить оконные функции для более элегантного решения:
SELECT last_name, count
FROM (
SELECT last_name, COUNT(*) AS count,
RANK() OVER (ORDER BY COUNT(*) DESC) AS rnk
FROM actor
GROUP BY last_name
) ranked
WHERE rnk = 1;Этот вариант также корректно обрабатывает ситуации с несколькими фамилиями-лидерами, присваивая каждой из них ранг 1.
Сравнение производительности
Для больших таблиц (сотни тысяч строк) подзапрос с HAVING может выполняться дольше из-за двойного сканирования. Оконные функции часто оказываются быстрее, но требуют поддержки со стороны СУБД. В таблице actor (обычно менее 200 записей) разница незаметна, поэтому можно выбирать любой читаемый вариант.
Практические рекомендации
- Точность: Если важно показать все фамилии-лидеры - используйте подзапрос или оконную функцию.
- Простота: Если достаточно одной фамилии (даже при совпадении count) -
LIMIT 1вполне уместен. - Индексация: Для ускорения группировки по
last_nameполезно создать индекс на этот столбец.
Вывод
Задача поиска самой популярной фамилии среди актеров решается разными способами. Базовый запрос с GROUP BY, ORDER BY и LIMIT 1 прост и эффективен, когда нужна одна запись. Для полного списка фамилий-лидеров лучше использовать подзапрос с HAVING или оконную функцию RANK(). Выбор зависит от требований к точности и версии СУБД.