{"id":14294,"url":"\/distributions\/14294\/click?bit=1&hash=434adac65d5ae5d3e2e945d184806550325dd9068ef9e9c0681ca88ae4a51357","hash":"434adac65d5ae5d3e2e945d184806550325dd9068ef9e9c0681ca88ae4a51357","title":"\u0412\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0418\u0418 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u043e\u0441\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f\u043c \u043c\u0438\u043b\u043b\u0438\u0430\u0440\u0434\u044b \u0432 \u0433\u043e\u0434","buttonText":"","imageUuid":""}

Взламываем SQL-интервью на позиции в «Тинькофф» и в «Альфа-Банк»

Давайте разберём задачи по SQL, которые могут встретиться на интервью у таких крупных компаний, как «Тинькофф» и «Альфа-Банк».

Хитрые теоретические вопросы по SQL от Тинькофф

1) Может ли измениться результат запроса, если в LEFT JOIN поменять местами таблицы?
Да, если поменять местами таблицы в LEFT JOIN, результат запроса кардинально изменится. Все потому, что LEFT JOIN берет все строки из «левой» таблицы, дополняя их данными из «правой». Смена мест изменяет логику: теперь «правая» становится «левой» и наоборот. Это влияет на то, какие строки и как будут включены в результат.

2) 5 + NULL — это сколько?
В SQL, когда вы выполняете арифметическую операцию с NULL, результатом всегда будет NULL. Это связано с тем, что NULL представляет собой неопределенное значение, и любая операция с неопределенным значением также является неопределенной. Таким образом, 5 + NULL будет равно NULL.

3) Можно ли делать JOIN таблицы саму на себя?
Абсолютно! Это называется self-join и полезно для работы с иерархическими данными или для сравнения строк в таблице. Вот пример запроса:

SELECT e.EmployeeName AS Employee, m.EmployeeName AS Manager FROM Employees e JOIN Employees m ON e.ManagerID = m.EmployeeID

В этом примере таблица Employees соединяется сама с собой для того, чтобы получить имя сотрудника (Employee) и его непосредственного руководителя (Manager). Таблице Employees присваиваются два разных алиаса: e для сотрудников и m для руководителей. Условие соединения e.ManagerID = m.EmployeeID позволяет соединить сотрудников с их руководителями по идентификаторам.

4) Какой из операторов SELECT, FROM, WHERE, GROUP BY выполняется последним?
Тут главный герой — SELECT! Хотя он стоит на первом месте по синтаксису, логически данные выбираются после всех фильтраций и группировок. Так что, порядок такой:
1. FROM → 2. WHERE → 3. GROUP BY → 4. SELECT

5) Минимальное и максимальное количество записей в FULL JOIN таблицы на 10 и 100 строк?

С FULL JOIN всё работает так:
Минимум — 100 строк, если каждая из 10 нашла свою пару.
Максимум — 1000 строк, если каждая строка из одной таблицы сопоставляется с каждой строкой из другой таблицы, то получаем кросс-продукт (декартово произведение) этих таблиц, что означает, что каждая строка из таблицы на 10 строк будет соединена с каждой строкой из таблицы на 100 строк.

Задача с собеседования в Альфа-Банк №1:

Вывести имена покупателей, каждый из которых приобрёл Laptop и Monitor (использовать наименование товара product.name) в марте 2024 года.

Схема БД

Относительно несложная задача. Попробуйте решить её самостоятельно в онлайн тренажёре.

Ход решения:

Шаг 1. Для начала давайте соединим 3 таблицы:
— Customer (клиенты) с Purchase (покупки) по customer_key,
— Purchase с Product (продукты) по product_key.

SELECT Customer.name FROM Customer JOIN Purchase ON Customer.customer_key = Purchase.customer_key JOIN Product ON Purchase.product_key = Product.product_key ...

Шаг 2. Далее нам необходимо отфильтровать записи в соответствии с условиями по наименованию товара и дате.

Добавим следующие фильтры в оператор WHERE:
— Product.name IN ("Laptop", "Monitor"),
— MONTH(Purchase.date) = 3 AND YEAR(Purchase.date) = 2024.

SELECT Customer.name FROM Customer JOIN Purchase ON Customer.customer_key = Purchase.customer_key JOIN Product ON Purchase.product_key = Product.product_key WHERE Product.name IN ('Laptop', 'Monitor') AND MONTH(Purchase.date) = 3 AND YEAR(Purchase.date) = 2024 ...

Шаг 3. Теперь с помощью GROUP BY Customer.customer_key cгруппируем данные по каждому клиенту, чтобы можно было агрегировать информацию о покупках на уровне отдельного клиента.

Шаг 4. И, наконец, с помощью HAVING COUNT(DISTINCT Product.name) = 2 отфильтруем уже сгруппированные данные и оставим только те группы клиентов, которые совершили покупку обоих товаров — Laptop и Monitor.

Итоговое решение:

SELECT Customer.name FROM Customer JOIN Purchase ON Customer.customer_key = Purchase.customer_key JOIN Product ON Purchase.product_key = Product.product_key WHERE Product.name IN ('Laptop', 'Monitor') AND MONTH(Purchase.date) = 3 AND YEAR(Purchase.date) = 2024 GROUP BY Customer.customer_key HAVING COUNT(DISTINCT Product.name) = 2

Задача с собеседования в Альфа-Банк №2:

Найдите средний возраст клиентов, приобретавших Smartwatch в 2024 году.

Схема БД

Задача среднего уровня сложности, чуть посложнее предыдущей. Её вы можете также попробовать решить самостоятельно в онлайн тренажёре.

Ход решения:

Шаг 1. Для начала необходимо соединить все необходимые таблицы:
— Customer и Purchase по customer_key,
— Purchase и Product по ключу product_key.

Шаг 2. Далее, необходимо отфильтровать данные в соответствии с условием задачи:
— по названию продукта: Product.name = "Smartwatch",
— по году покупки: YEAR(Purchase.date) = 2024.

На данном шаге мы имеем следующий запрос:

SELECT ... FROM Purchase JOIN Customer ON Purchase.customer_key = Customer.customer_key JOIN Product ON Purchase.product_key = Product.product_key WHERE Product.name = 'Smartwatch' AND YEAR(Purchase.date) = 2024

Шаг 3. Для того чтобы учесть каждого клиента только один раз, вне зависимости от количества покупок, совершённых им, необходимо получить уникальные записи с идентификаторами клиентов и их возрастами.

SELECT DISTINCT Customer.customer_key, Customer.age FROM Purchase JOIN Customer ON Purchase.customer_key = Customer.customer_key JOIN Product ON Purchase.product_key = Product.product_key WHERE Product.name = 'Smartwatch' AND YEAR(Purchase.date) = 2024

Шаг 4. Теперь, когда мы имеем список уникальных пользователей и их возрастов, мы можем произвести расчет среднего возраста клиентов. Для этого используем функцию AVG().

Итого, мы получаем следующий запрос:

SELECT AVG(uniqueCustomers.age) AS average_age FROM ( SELECT DISTINCT Customer.customer_key, Customer.age FROM Purchase JOIN Customer ON Purchase.customer_key = Customer.customer_key JOIN Product ON Purchase.product_key = Product.product_key WHERE Product.name = 'Smartwatch' AND YEAR(Purchase.date) = 2024 ) AS uniqueCustomers

Кроме того, на сайте SQL Academy есть задачи с собеседований других крупных компаний. Заходите, решайте, и удачи на собеседованиях!

Также мы активно ведём наш телеграм-канал с полезной информацией по SQL.

0
51 комментарий
Написать комментарий...
Alexey Zamesov

Скажите, а как FROM можно назвать оператором? У меня кровь из глаз пошла читая объяснение про «какой оператор выполняется последним». Тут скорее подходит обьяснение что SELECT это единственный оператор из предложенного, все что кроме него, это параметры

Ответить
Развернуть ветку
Alexey Zamesov

Соответственно, он и первый и последний

Ответить
Развернуть ветку
3 комментария
Nikolay Vavilov
Ответить
Развернуть ветку
2 комментария
Nikolay Vavilov

Первые 5 вопросов они еще на hr-скрининге на системного без предупреждения спрашивают - кекнул с этого.
5+ NULL отдельный кек - не могу представить такого кейса.
а так- sql-ex первые 100 пройдите и к любому скуль-интервью будете в принципе готовы, да про explain углубленно почитать.

Ответить
Развернуть ветку
Банан

5+NULL - например у тебя задача к каждой цене в прайслисте добавить 5 рублей себе на пиво. Для товара Х цена не нашлась, подзапрос вернул NULL, тогда общая цена будет тоже NULL, это логично

Ответить
Развернуть ветку
5 комментариев
Александр А.

Чо, правда, начинающий системный аналитик должен у этих работодателей понимать выдачу explain?

И как он будет это использовать в своей работе, интересно...

Ответить
Развернуть ветку
2 комментария
Тоже хочу

Устраиваться в Тинькофф чтобы работать за копейки?

Ответить
Развернуть ветку
Тимур Конжаков

Так написано же, что от

Ответить
Развернуть ветку
3 комментария
Тинькофф

Здравствуйте.

Доход в карточке вакансии - от указанной суммы. Фактическое вознаграждение обсуждаем с кандидатом уже при этапах собеседования и выбора более точной позиции.

Ответить
Развернуть ветку
7 комментариев
Андрей Захаров

К слову сказать, там написано "или удаленно".
Если работать удалено из условной деревни ,то даже эти минимальные 150 КРуб могут оказаться конкурентоспособным предложением.

Ответить
Развернуть ветку
2 комментария
Центр принятия решений

Дело даже не в деньгах. А в том, что компания такая отвратная. Репутация ниже плинтуса. А отношение к сотрудникам там даже хуже, чем к клиентам

Ответить
Развернуть ветку
Людмила

а планируется добавление заданий из собеседований в Сбер ?

Ответить
Развернуть ветку
Николай Ладанов
Автор

Ага, как раз на следующей неделе планировали добавить ✨

Ответить
Развернуть ветку
Сергей Николаев

Вопросы выглядят достаточно базовыми. Если собеседуемый не понимает даже их, то вопрос чуть в сторону и сразу становится понятно.

Прокатит, если вопросы задаются тупо зачитыванием по списку.

Ответить
Развернуть ветку
Николай Ладанов
Автор

Вопросы взяты из собеседования на позицию intern аналитик

Ответить
Развернуть ветку
1 комментарий
Аккаунт удален

Комментарий недоступен

Ответить
Развернуть ветку
2 комментария
Nikolay Vavilov

Базовое -это Инманн и Кимбалл

Ответить
Развернуть ветку
Тимофей Измайлов

Я бы подумал дважды, прежде чем в тиньк идти. Чего ради, потренировать стрессоустойчивость?

Ответить
Развернуть ветку
Тинькофф

Здравствуйте.

Подскажите, пожалуйста, с чем связаны ваши сомнения?

Ответить
Развернуть ветку
2 комментария
Michail

sql-ex правда хорош для подготовки, но в sql academy интерфейс поприятнее

Ответить
Развернуть ветку
Сергей Коновалов
Взламываем SQL-интервью на позиции в

Смысл уже сломали. Осталось дело за малым.

Ответить
Развернуть ветку
AlexStork

В решении задачи о Laptop и Monitor ошибка. При группировке по полю Customer.customer_key в SELECT мы должны указать агрегат для поля, не содержащемуся в GROUP BY, иначе получим ошибку Column 'Customer.name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Следует написать например MAX(Customer.name)

По крайней мере, это справедливо для MS SQL. Но в тренажере почему-то работает.

Ответить
Развернуть ветку
48 комментариев
Раскрывать всегда