Хотя составление SQL-запросов — это не самое интересное в работе дата-сайентистов, хорошее понимание SQL чрезвычайно важно для того, кто хочет преуспеть в любом занятии, связанном с обработкой данных. Дело тут в том, что SQL — это не только
Автор статьи, перевод которой мы сегодня публикуем, говорит, что она направлена на решение двух задач:
В статье рассмотрено 5 вопросов по SQL, взятых с Leetcode. Они представляют собой практические задачи, которые часто встречаются на собеседованиях.
Напишите SQL-запрос для получения из таблицы со сведениями о заработной плате сотрудников (
Например, такой запрос, выполненный для таблицы, представленной ниже, должен вернуть
▍Решение А: использование
Вот основные механизмы, которые будут использованы в данном варианте решения задачи:
Вот — готовый запрос:
▍Решение B: использование
В запросе, представленном ниже, используется функция
Напишите SQL-запрос, который обнаружит в таблице
▍Решение А:
Сначала мы создаём подзапрос, в котором выясняется частота появления каждого адреса в таблице. Затем результат, возвращаемый подзапросом, фильтруется с использованием инструкции
▍Решение B: выражение
Напишите SQL-запрос, который находит в таблице
▍Решение:
Если сформулировать обычным языком следующий запрос, то окажется, что он выражает следующую идею: нужно выбрать такие идентификаторы, чтобы температура, соответствующая представляемым ими датам, была бы больше, чем температура на «вчерашние» по отношению к ним даты.
В таблице
В таблице
Напишите SQL-запрос, который находит в каждом из подразделений сотрудников с максимальной заработной платой. Например, для вышеприведённых таблиц подобный запрос должен возвращать результаты, представленные следующей таблицей (при этом порядок строк в таблице значения не имеет):
▍Решение: команда
Команда
Здесь мы хотим получить таблицу, содержащую название подразделения (
Мэри — учительница в средней школе. У неё есть таблица
Вот таблица исходного размещения учеников:
Вот что должно получиться после пересаживания соседних учеников:
Напишите запрос, который позволит учительнице решить вышеописанную задачу.
Обратите внимание на то, что если количество учеников является нечётным — последнего ученика никуда пересаживать не надо.
▍Решение: использование оператора
SQL-конструкцию
В нашем случае первый оператор
Мы разобрали несколько задач по SQL, попутно обсудив некоторые продвинутые средства, которые можно использовать при составлении SQL-запросов. Надеемся, то, что вы сегодня узнали, пригодится вам при прохождении собеседований по SQL и окажется полезным в повседневной работе.
P.S. В нашем маркетплейсе есть Docker-образ с SQL Server Express, который устанавливается в один клик. Вы можете проверить работу контейнеров на VPS. Всем новым клиентам бесплатно предоставляются 3 дня для тестирования.
Уважаемые читатели! Что вы можете посоветовать тем, кто хочет освоить искусство создания SQL-запросов?
SELECT
, FROM
и WHERE
. Чем больше SQL-конструкций знает специалист — тем легче ему будет создавать запросы на получение из баз данных всего, что ему может понадобиться.Автор статьи, перевод которой мы сегодня публикуем, говорит, что она направлена на решение двух задач:
- Изучение механизмов, которые выходят за пределы базового знания SQL.
- Рассмотрение нескольких практических задач по работе с SQL.
В статье рассмотрено 5 вопросов по SQL, взятых с Leetcode. Они представляют собой практические задачи, которые часто встречаются на собеседованиях.
Вопрос №1: второе место по зарплате
Напишите SQL-запрос для получения из таблицы со сведениями о заработной плате сотрудников (
Employee
) записи, содержащей вторую по размеру заработную плату.Например, такой запрос, выполненный для таблицы, представленной ниже, должен вернуть
200
. Если в таблице нет значения, меньшего, чем самая высокая зарплата — запрос должен вернуть null
.+----+--------+
| Id | Salary |
+----+--------+
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
+----+--------+
▍Решение А: использование IFNULL
и OFFSET
Вот основные механизмы, которые будут использованы в данном варианте решения задачи:
IFNULL(expression, alt)
: эта функция возвращает свой аргументexpression
в том случае, если он не равенnull
. В противном случае возвращается аргументalt
. Мы воспользуемся этой функцией для того чтобы возвратитьnull
в том случае, если в таблице не окажется искомого значения.OFFSET
: этот оператор используется с выражениемORDER BY
для того чтобы отбросить первыеn
строк. Это нам пригодится по той причине, что нас интересует вторая строка результата (то есть — вторая по величине зарплата, данные о которой есть в таблице).
Вот — готовый запрос:
SELECT
IFNULL(
(SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET 1
), null) as SecondHighestSalary
FROM Employee
LIMIT 1
▍Решение B: использование MAX
В запросе, представленном ниже, используется функция
MAX
. Здесь выбирается самое большое значение заработной платы, не равное максимальной заработной плате, полученной по всей таблице. В результате мы и получаем то, что нам нужно — вторую по величине заработную плату.SELECT MAX(salary) AS SecondHighestSalary
FROM Employee
WHERE salary != (SELECT MAX(salary) FROM Employee)
Вопрос №2: дублирующиеся адреса электронной почты
Напишите SQL-запрос, который обнаружит в таблице
Person
все дублирующиеся адреса электронной почты.+----+---------+
| Id | Email |
+----+---------+
| 1 | a@b.com |
| 2 | c@d.com |
| 3 | a@b.com |
+----+---------+
▍Решение А: COUNT
в подзапросе
Сначала мы создаём подзапрос, в котором выясняется частота появления каждого адреса в таблице. Затем результат, возвращаемый подзапросом, фильтруется с использованием инструкции
WHERE count > 1
. Запрос вернёт сведения об адресах, встречающихся в исходной таблице больше одного раза.SELECT Email
FROM (
SELECT Email, count(Email) AS count
FROM Person
GROUP BY Email
) as email_count
WHERE count > 1
▍Решение B: выражение HAVING
HAVING
: это выражение, которое позволяет использовать инструкциюWHERE
вместе с выражениемGROUP BY
.
SELECT Email
FROM Person
GROUP BY Email
HAVING count(Email) > 1
Вопрос №3: растущая температура
Напишите SQL-запрос, который находит в таблице
Weather
все даты (идентификаторы дат), когда температура была бы выше температуры на предшествующие им даты. То есть, нас интересуют даты, в которые «сегодняшняя» температура выше «вчерашней».+---------+------------------+------------------+
| Id(INT) | RecordDate(DATE) | Temperature(INT) |
+---------+------------------+------------------+
| 1 | 2015-01-01 | 10 |
| 2 | 2015-01-02 | 25 |
| 3 | 2015-01-03 | 20 |
| 4 | 2015-01-04 | 30 |
+---------+------------------+------------------+
▍Решение: DATEDIFF
DATEDIFF
: эта функция вычисляет разницу между двумя датами. Она используется для того, чтобы обеспечить сравнение именно «сегодняшних» и «вчерашних» температур.
Если сформулировать обычным языком следующий запрос, то окажется, что он выражает следующую идею: нужно выбрать такие идентификаторы, чтобы температура, соответствующая представляемым ими датам, была бы больше, чем температура на «вчерашние» по отношению к ним даты.
SELECT DISTINCT a.Id
FROM Weather a, Weather b
WHERE a.Temperature > b.Temperature
AND DATEDIFF(a.Recorddate, b.Recorddate) = 1
Вопрос №4: самая высокая зарплата в подразделении
В таблице
Employee
хранятся сведения о сотрудниках компании. В каждой записи этой таблицы содержатся сведения об идентификаторе (Id
) сотрудника, о его имени (Name
), о зарплате (Salary
) и о подразделении компании, где он работает (Department
).+----+-------+--------+--------------+
| Id | Name | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Jim | 90000 | 1 |
| 3 | Henry | 80000 | 2 |
| 4 | Sam | 60000 | 2 |
| 5 | Max | 90000 | 1 |
+----+-------+--------+--------------+
В таблице
Department
содержатся сведения о подразделениях компании.+----+----------+
| Id | Name |
+----+----------+
| 1 | IT |
| 2 | Sales |
+----+----------+
Напишите SQL-запрос, который находит в каждом из подразделений сотрудников с максимальной заработной платой. Например, для вышеприведённых таблиц подобный запрос должен возвращать результаты, представленные следующей таблицей (при этом порядок строк в таблице значения не имеет):
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Max | 90000 |
| IT | Jim | 90000 |
| Sales | Henry | 80000 |
+------------+----------+--------+
▍Решение: команда IN
Команда
IN
позволяет задавать в инструкции WHERE
условия, соответствующие использованию нескольких команд OR
. Например, две следующие конструкции идентичны:WHERE country = ‘Canada’ OR country = ‘USA’
WHERE country IN (‘Canada’, ’USA’).
Здесь мы хотим получить таблицу, содержащую название подразделения (
Department
), имя сотрудника (Employee
) и его заработную плату (Salary
). Для этого мы формируем таблицу, в которой содержатся сведения об идентификаторе подразделения (DepartmentID
) и о максимальной зарплате по этому подразделению. Далее мы объединяем две таблицы по условию, в соответствии с которым записи в результирующую таблицу попадают только в том случае, если DepartmentID
и Salary
есть в ранее сформированной таблице.SELECT
Department.name AS 'Department',
Employee.name AS 'Employee',
Salary
FROM Employee
INNER JOIN Department ON Employee.DepartmentId = Department.Id
WHERE (DepartmentId , Salary)
IN
( SELECT
DepartmentId, MAX(Salary)
FROM
Employee
GROUP BY DepartmentId
)
Вопрос №5: пересаживание учеников
Мэри — учительница в средней школе. У неё есть таблица
seat
, хранящая имена учеников и сведениях об их местах в классе. Значение id
в этой таблице постоянно возрастает. Мэри хочет поменять местами соседних учеников.Вот таблица исходного размещения учеников:
+---------+---------+
| id | student |
+---------+---------+
| 1 | Abbot |
| 2 | Doris |
| 3 | Emerson |
| 4 | Green |
| 5 | Jeames |
+---------+---------+
Вот что должно получиться после пересаживания соседних учеников:
+---------+---------+
| id | student |
+---------+---------+
| 1 | Doris |
| 2 | Abbot |
| 3 | Green |
| 4 | Emerson |
| 5 | Jeames |
+---------+---------+
Напишите запрос, который позволит учительнице решить вышеописанную задачу.
Обратите внимание на то, что если количество учеников является нечётным — последнего ученика никуда пересаживать не надо.
▍Решение: использование оператора WHEN
SQL-конструкцию
CASE WHEN THEN
можно рассматривать как оператор if
в программировании.В нашем случае первый оператор
WHEN
используется для проверки того, назначен ли последней строке в таблице нечётный идентификатор. Если это так — строка не подвергается изменениям. Второй оператор WHEN
отвечает за добавление 1 к каждому нечётному идентификатору (например — 1, 3, 5 превращается в 2, 4, 6) и за вычитание 1 из каждого чётного идентификатора (2, 4, 6 превращаются в 1, 3, 5).SELECT
CASE
WHEN((SELECT MAX(id) FROM seat)%2 = 1) AND id = (SELECT MAX(id) FROM seat) THEN id
WHEN id%2 = 1 THEN id + 1
ELSE id - 1
END AS id, student
FROM seat
ORDER BY id
Итоги
Мы разобрали несколько задач по SQL, попутно обсудив некоторые продвинутые средства, которые можно использовать при составлении SQL-запросов. Надеемся, то, что вы сегодня узнали, пригодится вам при прохождении собеседований по SQL и окажется полезным в повседневной работе.
P.S. В нашем маркетплейсе есть Docker-образ с SQL Server Express, который устанавливается в один клик. Вы можете проверить работу контейнеров на VPS. Всем новым клиентам бесплатно предоставляются 3 дня для тестирования.
Уважаемые читатели! Что вы можете посоветовать тем, кто хочет освоить искусство создания SQL-запросов?