Достаточно часто во время интервью приходиться сталкиваться с вопросами по SQL. Сегодня поговорим о популярных вопросах, с которыми мне приходилось сталкиваться.
Самое интересное, что на интервью даже не пытаются придумать какие-то сложные примеры или схемы. Чаще всего приходилось писать запросы к какой-то гипотетической базе данных, в которой хранятся клиенты и их заказы. Да, это самый популярный был вопрос, а ведь чаще всего именно на подобных примерах учат в книгах и не удивлюсь, если на этом учат и в колледжах или институтах. Я самоучка, но дочка в колледже базы данных проходила как раз на подобных примерах.
Пару компаний просили накидать именно схему, а в Ceridian мы даже не напрягали кандидатов, а предлагали использовать тестовую базу данных Northwind, которая идет в составе MS SQL Server. Я думаю, я могу сейчас говорить про это, потому что мы это спрашивали последний раз уже 2 года назад и той команды нет. Никто больше в Ceridian не спрашивал так и когда меня нанимали, меня просили именно накидать базу, а не использовать готовую.
Я точно уже не помню вопросы по базам данных, которые были у нас в списке, потому что только пару человек при мне смогли дойти до конца, очень часто заваливались, не доходя до баз данных, а если и доходили до SQL, то и тут проваливались сразу же на первых вопросах.
Просишь – покажите счета, которые были заказаны, кажется в Лондоне, может в другом городе, точно не помню, но точно был город. Нужно догадаться, что кандидат должен выбрать данные из таблицы Order и связать с Customer и отфильтровать по колонке Город. Несколько человек не смогли найти таблицы, которые нужно связать или не смогли понять, по каким полям их связать. Внешние ключи, хорошее именование колонок – ничего не помогло этим кандидатам написать этот запрос.
Большинство при написании секции where Country = 'London' и приходилось подсказывать, что Лондон – это не страна. Конечно же на это мы ни разу не обращали внимания, а просто подсказывали и понимали, что это просто стресс и волнение.
Вообще использование популярной готовой базы данных или просьба накидать популярную задачу самому – на мой взгляд значительно упрощает процесс прохождения теста. Знакомая задача, должна сократить стресс у кандидата до минимума.
Если вам дали готовую базу данных, то внимательно смотрите на имена колонок. Если нужно вязать таблицы Customer и Order, то просто открываем обе этих таблицы и ищем колонку, имя которой есть и там и там.
Обычно колонки, по которым происходит связь, имеют одно и то же имя, причем имя колонки чаще всего будет такое же, как и имя таблицы с каким-то префиксом. Так что скорей всего в таблице Order есть колонка CustomerID или в таблице Customer есть колонка OrderID. Опытный программист скажет, что второй вариант абсолютно не имеет смысла, скорей всего нужно искать первый. Но даже если опыта нет и нервы не дают мыслям собраться, ищите, банальное сравнение решит вопрос.
Если скажут делать самому схему, то скорей всего нужно будет просто нарисовать ее, а не писать конкретный SQL запрос.
Имея такую схему, очень часто спрашивают найти клиентов, у которых нет заказов. Эту задачу можно решить с помощью EXISTS, а можно с помощью LEFT JOIN, причем можно показать оба решения:
Select *
from Customer c
left join [Order] o on c.CustomerID = c.CustomerID
where o.CustomerID is null
Будет круто, если вы укажите Order в кавычках ` для MySql или в квадратных скобках для MS SQL, чтобы показать, что вы видите возможную проблему с зарезервированным словом Order.
Второе решение этой же задачи:
Select *
from Customer c
where not exists (select null from [Order] o where c.CustomerID = c.CustomerID)
Очень часто просят найти что-то очень популярное, например, в данном случае это может быть три клиента, которые купили, поместили больше всего заказов.
В случае с MS SQL Server можно использовать rownum и partition by, но если нужно просто три самых популярных, то rownum будет избыточным. partition by необходим, когда нужно три самых популярных в определенной группе и partition by как раз задает эту группу.
То есть если спрашивают 3 самых популярных по стране, то вот это как раз признак на то, что нужно partition by.
Чаще всего просто спрашивают 3 самых популярных среди всех, тогда можно написать решение, которое работает практически вне зависимости от базы данных.
Итак, решим эту задачу. Раз нужны популярные, значит нужно количество. Популярные клиенты, значит количество по клиенту, а это group by:
Select customerid, count(*)
From [order]
Group by customerid
Теперь нужны самые самые из них, а значит нужно отсортировать:
Select customerid, count(*)
From [order]
Group by customerid
Order by 2 desc
Из них нужно взять три первых, а это для MS SQL Server TOP, а для MySQL limit. Только 3 первых нужно получить от результата этого за проса. Если написать так:
Select top 3 customerid, count(*)
From [order]
Group by customerid
Order by 2 desc
То мы возьмем первые три и посчитаем количество, а нужно сначала посчитать, а потом взять три:
Select top 3 customerid, count(*)
From [order]
Group by customerid
Order by 2 desc
Остается только JOIN на Customer сделать.
Некоторые идут дальше и просят накидать схему многие ко многим и в таких случаях я чаще всего видел задачи на примере курсов и студентов. Есть студенты и есть курсы. Один студент может подписаться на несколько курсов. Но может быть и наоборот много студентов на один курс. Классическая задача на многие ко многим.
Более сложных задач я не встречал на собеседованиях программиста. Возможно, для программистов баз данных бывает, но даже для Full Stack пока не встречал.
Внимание!!! Если ты копируешь эту статью себе на сайт, то оставляй ссылку непосредственно на эту страницу. Спасибо за понимание
Автору респект. Есть пожелание в тексте выделять код как-то, а то не очень читабельно.