SQL — это универсальный язык для взаимодействия с базами данных, который должен знать каждый аналитик, разработчик и дата-инженер. На собеседованиях кандидатам часто предлагают решить практические задачи: написать эффективные запросы, оптимизировать их и предложить решение для конкретных бизнес-кейсов. Давай разберём распространённые типы SQL-задач и эффективные подходы к их решению.
Предыдущее задание:
Постановка задачи
Требуется вывести пассажиров, чьё полное имя (ФИО) имеет максимальную длину среди всех записей в базе. Важные условия:
- Все символы в имени учитываются (включая пробелы, дефисы и точки)
- Необходимо найти всех пассажиров с максимальной длиной имени (если таких несколько)
- Результирующая таблица должна содержать только поле name
Анализ структуры базы данных
Для решения задачи нам понадобится таблица:
- Passenger — содержит информацию о пассажирах, включая:
name — полное имя пассажира (поле для анализа)
Другие поля (не требуются для решения этой задачи)
Детальный разбор решения
SQL-запрос
SELECT name
FROM passenger
WHERE LENGTH(name) = (SELECT MAX(LENGTH(name)) FROM passenger);
Пошаговое объяснение:
- Подзапрос (внутренний SELECT):
SELECT MAX(LENGTH(name)) FROM passenger — находит максимальную длину имени в таблице - Основной запрос:
WHERE LENGTH(name) = ... — сравнивает длину каждого имени с максимальной
SELECT name — выводит только поле с именем
Ключевые аспекты решения
1. Функция LENGTH
- Функция LENGTH() возвращает количество символов в строке
- Учитывает все символы, включая пробелы и знаки препинания
- В разных СУБД могут быть аналоги (LEN() в SQL Server, LENGTH() в MySQL)
2. Подзапрос для нахождения максимума
- Вложенный запрос вычисляет максимальное значение длины имени
- Это значение затем используется в основном запросе для фильтрации
- Альтернатива — использование оконных функций (более современный подход)
3. Учёт всех пассажиров с максимальной длиной
- Запрос автоматически находит всех пассажиров с именем максимальной длины
- Не требует дополнительной обработки для случая нескольких результатов
Возможные модификации запроса
1. С использованием оконных функций (более эффективно)
WITH RankedPassengers AS (
SELECT name, LENGTH(name) as name_length,
DENSE_RANK() OVER (ORDER BY LENGTH(name) DESC) as rank
FROM passenger
)
SELECT name
FROM RankedPassengers
WHERE rank = 1;
2. С добавлением информации о длине имени
SELECT name, LENGTH(name) as name_length
FROM passenger
WHERE LENGTH(name) = (SELECT MAX(LENGTH(name)) FROM passenger);
Оптимизация запроса
Для больших таблиц:
- Создать вычисляемый столбец с длиной имени и индекс на него
- Использовать оконные функции вместо подзапроса
- Для очень больших таблиц — материализованное представление
Частые ошибки
- Использование LEN вместо LENGTH (или наоборот) для конкретной СУБД
- Забыть учесть, что максимальная длина может быть у нескольких пассажиров
- Попытка использовать GROUP BY без необходимости
- Неучёт всех символов (например, с помощью TRIM перед вычислением длины)
Дополнительные соображения
- В реальных базах могут быть особенности хранения ФИО
- Для Unicode-символов может потребоваться специальная обработка
- Можно расширить запрос для анализа структуры самых длинных имён
Заключение
Данная задача демонстрирует:
- Работу со строковыми функциями
- Использование подзапросов для агрегатных вычислений
- Особенности поиска экстремальных значений в SQL
🔑 Итоговое решение:
SELECT name
FROM passenger
WHERE LENGTH(name) = (SELECT MAX(LENGTH(name)) FROM passenger);
Альтернативное решение с оконными функциями:
SELECT name
FROM (
SELECT name, DENSE_RANK() OVER (ORDER BY LENGTH(name) DESC) as rank
FROM passenger
) ranked
WHERE rank = 1;