Вопросы по SQL и PostgreSQL на собеседовании: ответы и задачи
Для подготовки к SQL-собеседованию важно не только воспроизвести определение, но и объяснить результат запроса: что произойдёт с NULL, дубликатами, группировкой и порядком строк. Ниже — вопросы с короткими ответами и три задачи с решениями. Примеры используют синтаксис PostgreSQL; различия диалектов отмечены в ответах.
Начните с JOIN, GROUP BY, NULL и агрегатов, затем переходите к оконным функциям, индексам и транзакциям. Сначала решите задачу самостоятельно, затем сравните результат.
18 вопросов по SQL и PostgreSQL с ответами
1. Чем WHERE отличается от HAVING?
WHERE отбирает исходные строки, HAVING — группы после группировки. Условие на сумму группы обычно относится в HAVING.
2. Чем INNER JOIN отличается от LEFT JOIN?
INNER JOIN оставляет совпавшие пары. LEFT JOIN сохраняет строки слева без совпадения, дополняя правую часть NULL. Фильтр по правой таблице в WHERE может исключить эти строки.
3. Почему JOIN увеличил число строк?
Ключ соединения может быть неуникальным. При связи многие-ко-многим каждая строка соединяется с несколькими строками другой таблицы. Сначала проверьте кратность ключей.
4. Чем COUNT(*) отличается от COUNT(column)?
COUNT(*) считает строки, COUNT(column) — строки с ненулевым в смысле NULL значением столбца. Число 0 при этом учитывается.
5. Почему column = NULL не работает?
Обычное сравнение с NULL даёт неизвестный результат. Для проверки отсутствия значения используйте IS NULL или IS NOT NULL.
6. Чем UNION отличается от UNION ALL?
UNION убирает дубликаты результирующих строк, UNION ALL сохраняет их. Число столбцов и типы соответствующих позиций должны быть совместимы.
7. Что такое PRIMARY KEY?
Ограничение уникальности и отсутствия NULL, идентифицирующее строку. Ключ может состоять из нескольких столбцов; у таблицы не более одного PRIMARY KEY.
8. INDEX — это ограничение?
Обычный индекс ускоряет определённые способы доступа и сам по себе не задаёт бизнес-ограничение. UNIQUE-индекс дополнительно обеспечивает уникальность. Не путайте DEFAULT с проверкой допустимости значений.
9. Что запрещает NOT NULL?
Отсутствие значения NULL. Ноль и пустая строка не являются NULL и сами по себе этим ограничением не запрещены.
10. Что гарантирует FOREIGN KEY?
Ссылочную целостность: ненулевой ключ должен соответствовать допустимому ключу в связанной таблице. Ссылка возможна не только на PRIMARY KEY; важны требования СУБД к уникальности.
11. Чем оконная функция отличается от GROUP BY?
Оконная функция вычисляет значение по набору связанных строк, сохраняя отдельные строки результата. GROUP BY сворачивает строки в группы.
12. Когда использовать ROW_NUMBER, RANK и DENSE_RANK?
ROW_NUMBER нумерует строки; RANK присваивает одинаковый ранг равным значениям с пропусками далее; DENSE_RANK — без пропусков. При равенстве задайте дополнительный порядок, если нужен единственный результат.
13. Можно ли откатить TRUNCATE в PostgreSQL?
Да, если окружающая транзакция не зафиксирована. TRUNCATE очищает все строки и берёт сильную блокировку; для части строк нужен DELETE с WHERE.
14. Зачем нужен индекс и почему его не использовали?
Индекс имеет стоимость хранения и изменения. Планировщик может предпочесть последовательное чтение, если оно дешевле. Изучите селективность, статистику и план, а не только наличие индекса.
15. Что показывает EXPLAIN ANALYZE?
Фактическое выполнение и статистику плана. Команда действительно исполняет запрос; для изменяющих запросов учитывайте побочные эффекты и используйте отдельный стенд.
16. Что такое MVCC?
Механизм работы с версиями строк, который позволяет транзакциям читать согласованные снимки. Видимость зависит от уровня изоляции и момента снимка.
17. Зачем VACUUM?
В PostgreSQL он обслуживает версии строк и освобождает место для повторного использования, а также решает задачи заморозки идентификаторов транзакций. Обычный VACUUM не равен полному возврату файла таблицы операционной системе.
18. Чем CTE отличается от временной таблицы?
CTE задаёт именованный подзапрос в одной SQL-команде. Временная таблица — отдельный объект сеанса. Поведение материализации CTE зависит от запроса и версии СУБД.
Задачи: данные, запрос и ожидаемый результат
1. Найдите клиентов без заказов
Нужно сохранить клиента даже при отсутствии строк справа. Все входные данные заданы в запросе:
WITH customers(id) AS (VALUES (1),(2),(3)),
orders(customer_id) AS (VALUES (1),(1),(2))
SELECT c.id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.customer_id IS NULL
ORDER BY c.id;
-- 32. Покажите клиентов с суммой заказов больше 100
WITH orders(customer_id, amount) AS (
VALUES (1, 80), (1, 40), (2, 90)
)
SELECT customer_id, sum(amount) AS total
FROM orders
GROUP BY customer_id
HAVING sum(amount) > 100
ORDER BY customer_id;
-- 1 | 120
Условие WHERE amount > 100 здесь дало бы другой ответ: оно проверяет каждый заказ, а не сумму клиента.
3. Найдите последний заказ каждого клиента
WITH orders(id, customer_id, created_at) AS (
VALUES (10,1,DATE '2026-09-01'),
(11,1,DATE '2026-09-02'),
(12,1,DATE '2026-09-02'),
(13,2,DATE '2026-09-01')
), ranked AS (
SELECT *, row_number() OVER (
PARTITION BY customer_id ORDER BY created_at DESC, id DESC
) AS rn FROM orders
)
SELECT customer_id, id FROM ranked
WHERE rn = 1 ORDER BY customer_id;
-- 1 | 12
-- 2 | 13
Здесь при равной дате выбран больший ID. Это явное учебное правило разрешения равенства, а не доказательство более позднего события.
Как проверить готовность к интервью
Для каждого решения назовите ожидаемые строки, объясните работу NULL и дубликатов, предложите альтернативу и обсудите индекс для большого набора данных. Не приписывайте вопросы конкретным компаниям без проверяемого источника.
Для последовательной практики по запросам и устройству СУБД изучите программу курса по PostgreSQL. Короткий разбор удаления данных — в статье TRUNCATE TABLE в PostgreSQL.
Документация



