Обложка: 11 задач по SQL с собеседований на позицию Data Engineer

11 задач по SQL с собеседований на позицию Data Engineer

Мкртич Пудеян
Мкртич Пудеян

data-аналитик в ГК FINBRIDGE

Позиция data-инженера востребована в IT-индустрии. Такой специалист занимается обработкой данных, которые чаще всего хранятся в базах данных. Работа с БД, в свою очередь, подразумевает хорошее знание языка запросов SQL.

На собеседованиях в мобильном операторе мы для проверки у кандидата знаний SQL задавали небольшие, но хитрые задачи по запросам, которые будут описаны ниже. Некоторые из них вводили в ступор даже опытных разработчиков баз данных.

Итак, начнём. Представьте, что у вас в базе данных есть две таблицы: TABLE1 и TABLE2. Ниже будут приведены несколько SQL-запросов. Нужно ответить на один простой вопрос: отработает ли данный запрос или упадет с ошибкой? И объяснить, почему.

Задача 1

select * from TABLE1 group by ID

Вопрос с подвохом. Тут нет однозначного ответа, отработает или нет. Всё зависит от списка полей в таблице. Символ * эквивалентен перечислению всех полей таблицы. Если в таблице будет всего одно поле с названием id, то запрос отработает. Иначе — нет, потому что при наличии в таблице нескольких полей символ * будет означать перечисление всех полей, что в SQL требует перечисления искомого в конструкции GROUP BY. Либо кандидат должен уточнить, какие поля есть в таблице, дабы однозначно ответить на вопрос.  

Задача 2

select field1 from TABLE1 group by field1, field2

Да, отработает. В SQL допускается перечисление не всех полей в разделе SELECT, если мы группируемся по нескольким полям. В данном примере группировка выполняется по двум полям, а выводится на экран одно поле. А вот наоборот сделать уже нельзя.

Задача 3

select field1, field2 from TABLE1 group by field1, field2 having field2 = 0

Примечание: field1, field2 являются числовыми полями.

Да, отработает. В SQL можно в разделе having указывать поле, по которому выполняется  группировка. Несмотря на то, что на практике такое условие редко используется, подобный запрос можно выполнить. Чаще всего разработчики в конструкции having используют агрегирующую функцию — например, having count(*) >0. Эта задача рассчитана на то, чтобы сбить с толку. Кандидат, хорошо знающий язык SQL, ответит на вопрос уверенно, в то время как неопытный засомневается. Хотя могут быть исключения.

Задача 4

update TABLE1 set field1 = row_number() from TABLE1

Нет, не отработает. Опытный data-инженер знает, что row_number() — это часть аналитической функции, которая не может быть применена сама по себе. Аналитические функции  используются только в конcтрукциях SELECT или ORDER BY.

Задача 5

insert into TABLE1 (field1, field2, field3) values ('1','2')

Примечание: field1, field2, field3 являются текстовыми полями.

Здесь всё очень просто. При вставке строчек в таблицу количество полей при объявлении не соответствует количеству вставляемых значений в конструкции values. Это должен знать даже начинающий SQL-разработчик.

Задача 6

delete from TABLE1 having count(field1) > 1

Здесь тоже всё просто — запрос не отработает. Конструкция having не может использоваться при удалении строк. Она используется только при операции SELECT и чаще всего вместе  с группировкой строк (GROUP BY).  Эта  задачка рассчитана на новичков. Опытный SQLщик сразу ответит на вопрос.

Задача 7

truncate TABLE1

Тоже довольно простой вопрос. Разработчик, постоянно работающий с базами данных, сразу ответит, что будет ошибка. В запросе не хватает ключевого слова table, т.е. должно быть truncate table TABLE1. Также можно задать дополнительный вопрос: чем отличается truncate table TABLE1 от delete from TABLE1? Truncate — это DDL-операция, т.е. операция изменения объекта в базе. Она выполняется намного быстрее. Delete — это операция DML, т.е. операция с данными внутри таблицы. Опытный разработчик должен знать нюансы SQL.

Задача 8

select * from table1 as t inner join table2 as tt on 1 = tt.field1

Вопрос нацелен на то, чтобы сбить с толку кандидата. На практике при операции join в большинстве случаев выполняется жесткое сопоставление одного поля в одной таблице с  другим полем во второй. Например, t.field1 = tt.field1. В данном же случае запрос отработает. В этом примере выполняется сначала декартово произведение всех строк одной таблице со всем строками другой и затем применяется условие, что tt.field1 = 1. Такое написание допустимо, хотя и редко где применяется. Неопытные data-инженеры часто впадают в ступор на этой задаче.

Задача 9

select id,sum(value) over(partition by i order by y), * from table1

Примечание: все поля существуют в таблице и соответствуют нужному типу данных.

Да, отработает. Классический пример аналитической функции, внутри которой сначала выполняется группировка (partition by), потом выполняется сортировка (order by) и применяется агрегирующая функция. В данном случае все написано правильно. Этот вопрос проверяет у кандидата знание оконных функций.

Задача 10

select count(*) from table1 ,table2

Да, отработает. Такое написание синтаксиса допускается в SQL. В этом случае выполняется декартово произведение всех строк одной таблицы со всеми строками другой. Если её обогатить ещё конструкцией where с сопоставлением полей в таблицах table1 и table2, то получится классический inner join. На самом деле, это старый синтаксис внутреннего соединения таблиц. Обычно вместо нее рекомендуется использовать inner join или cross join из соображений оптимизации запросов.

Задача 11

select * from table1 where null = null or null <> null or 123 <> null or null is null

Примечание: представьте, что таблица table1 не пустая. Вернет ли этот запрос строки? Почему?

Да, вернет. Причина в последнем условии null is null. Оно указано правильно. Дело в том, что при операции сравнения (=, <> , > , <) значения null c каким-либо числом или полем всегда возвращается значение FALSE. Т.е. синтаксический запрос написан правильно и не упадет, но он отсекает строки.

NULL в базах данных — это специальное значение, которое может быть записано в поле таблицы. NULL соответствует понятию «пустое поле», т.е. «поле, не содержащее никакого значения». Но его нельзя сравнивать константой. NULL можно сравнивать только через оператор is т.е. null is null или field1 is null.

Конечно, существует еще 100500 задач, которые можно придумать и решать на собеседованиях. Но, по моему мнению, важнее всего показать верное направление мышления, чем дать правильный ответ на конкретный вопрос.


Если готовитесь к устройству на работу или хотите просто освежить знания, посмотрите ещё эти 5 заданий по SQL с реальных собеседований.

Хинт для программистов: если зарегистрируетесь на соревнования Huawei Cup, то бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.

Перейти к регистрации