SQL: тест продвинутого уровня
SQL — это язык, который позволяет не только выполнять простые операции с данными, но и строить сложные аналитические запросы, объединять множество таблиц и оптимизировать работу базы данных. Продвинутый уровень SQL требует глубоких знаний и навыков работы с базами данных, что и проверяется в тестах на различных сайтах, в том числе работодателям.
В этой статье мы разберем, как успешно пройти тест продвинутого уровня, который включает задания на выполнение сложных запросов, использование оконных функций (WINDOW FUNCTIONS), многотабличные объединения (MULTI-JOIN), а также анализ и оптимизацию сложных операций. Мы предоставим пример тестового задания, разберем каждый вариант ответа и объясним, как подойти к решению, чтобы продемонстрировать высокий уровень владения SQL.
👉🏻Навигация и ссылки по всем материалам в Telegram
Вопрос 1
Получите список имен и фамилий сотрудников, которые работают в отделе маркетинга, из таблицы Employees.
- CHOOSE first_name, last_name FROM Employees HAVING department = 'Marketing';
- SELECT first_name, last_name WHERE department = 'Marketing';
- SELECT first_name, last_name WHERE department = 'Marketing' FROM Employees;
- SELECT first_name, last_name FROM Employees WHERE department = 'Marketing';
- FROM Employees SELECT first_name, last_name WHERE department = 'Marketing';
Обоснование:
- CHOOSE first_name, last_name FROM Employees HAVING department = 'Marketing';
❌ Неверно. В SQL не существует команды CHOOSE. Также использование HAVING предполагает агрегатные функции, что здесь не требуется. - SELECT first_name, last_name WHERE department = 'Marketing';
❌ Неверно. Команда SELECT требует указания таблицы после выбранных полей. Здесь отсутствует ключевое слово FROM Employees, из-за чего запрос синтаксически некорректен. - SELECT first_name, last_name WHERE department = 'Marketing' FROM Employees;
❌ Неверно. Нарушен синтаксис SQL: ключевое слово FROM должно следовать сразу после команды SELECT, а затем список полей и название таблицы. - SELECT first_name, last_name FROM Employees WHERE department = 'Marketing';
✅ Правильно. Запрос корректен, так как использует правильный синтаксис:Команда SELECT для выбора полей first_name и last_name;
Ключевое слово FROM, чтобы указать таблицу Employees;
Условие WHERE, чтобы отфильтровать записи по значению department = 'Marketing'. - FROM Employees SELECT first_name, last_name WHERE department = 'Marketing';
❌ Неверно. Нарушен синтаксис SQL: ключевое слово FROM не может предшествовать SELECT.
📌Правильный ответ:
4. SELECT first_name, last_name FROM Employees WHERE department = 'Marketing';
Вопрос 2
Добавьте новый столбец email с типом данных VARCHAR(255) в существующую таблицу Clients.
- INTO TABLE Clients ADD email VARCHAR(255);
- ALTER TABLE Clients ADD email VARCHAR(255);
- UPDATE TABLE Clients ADD email VARCHAR(255);
- UPDATE TABLE Clients ALTER COLUMN email VARCHAR(255);
- ALTER TABLE Clients ALTER COLUMN email VARCHAR(255);
Обоснование:
- INTO TABLE Clients ADD email VARCHAR(255);
❌ Неверно. В SQL отсутствует команда INTO TABLE для добавления столбцов. Эта команда используется для добавления строк (INSERT INTO). - ALTER TABLE Clients ADD email VARCHAR(255);
✅ Правильно. Команда ALTER TABLE используется для изменения структуры таблицы. Ключевое слово ADD добавляет новый столбец.
Указывается имя столбца (email) и его тип данных (VARCHAR(255)). - UPDATE TABLE Clients ADD email VARCHAR(255);
❌ Неверно. Команда UPDATE предназначена для изменения значений в существующих строках, а не для изменения структуры таблицы. - UPDATE TABLE Clients ALTER COLUMN email VARCHAR(255);
❌ Неверно. Команда ALTER COLUMN используется для изменения параметров существующего столбца, а не для его добавления. Также UPDATE здесь некорректно. - ALTER TABLE Clients ALTER COLUMN email VARCHAR(255);
❌ Неверно. Команда ALTER COLUMN используется для изменения параметров уже существующего столбца. Здесь требуется добавить новый столбец, а не изменять существующий.
📌Правильный ответ:
2. ALTER TABLE Clients ADD email VARCHAR(255);
Вопрос 3
Каким будет результат выполнения следующего кода для таблицы Cars, если car_id — первичный ключ? На изображении — элементы вывода таблицы.
- Добавится новая запись (4, 5, 'BMW X5 M50d', Null)
- Заменится последняя запись на новую (3, 5, 'BMW X5 M50d', Null)
- Заменится последняя запись на новую (3, 5, 'BMW X5 M50d', 7)
- Добавится новая запись (Null, 5, 'BMW X5 M50d', Null)
- Отобразится ошибка
Обоснование:
1. Разбор синтаксиса команды:
Команда INSERT INTO добавляет новую строку в таблицу. Однако в SQL синтаксисе нужно явно указать, какие столбцы заполняются, если не все поля предоставляются, например:
INSERT INTO Cars (distributor_id, car_model)
VALUES (5, 'BMW X5 M50d');В данном коде это упущено.
2. Особенности первичного ключа (car_id):
Поле car_id — первичный ключ, которое:
- Не может быть NULL.
- Должно быть уникальным.
Поскольку в запросе отсутствует значение для car_id, SQL сгенерирует ошибку, если поле не настроено как автоинкремент.
3. Проблема в запросе:
Синтаксис VALUES distributor_id = 5, car_model = 'BMW X5 M50d' некорректен, так как значения передаются в неправильной форме. Следовательно, SQL не выполнит запрос и выдаст ошибку.
📌Правильный ответ:
Вопрос 4
Вы хотите найти заработную плату отделов, у которых общая заработная плата не превышает 700 000 рублей, в таблице Salaries. Какая ошибка допущена в запросе?
- Используется GROUP BY вместо GROUP
- HAVING total_salary <= 700000 стоит перед GROUP BY, а не после него
- Не должно использоваться GROUP BY
- Используется HAVING вместо WHERE
- Используется total_salary <= 700000 вместо SUM(salary) <= 700000
Обоснование:
- Синтаксис GROUP BY:
🤔Команда GROUP BY корректна и позволяет группировать данные по значениям столбца department_id. Здесь синтаксис правильный, поэтому вариант 1 неверен. - Позиция HAVING:
❌HAVING всегда используется после выполнения группировки (GROUP BY) для фильтрации результатов. В данном запросе HAVING используется после GROUP BY, как и должно быть. Поэтому вариант 2 неверен. - Не должно использоваться GROUP BY:
❌Это утверждение неверно, так как группировка по department_id необходима для вычисления суммы зарплат по каждому отделу. - Используется HAVING вместо WHERE:
❌Это утверждение тоже неверно. WHERE используется для фильтрации строк до группировки, а HAVING — для фильтрации уже агрегированных данных (например, суммы зарплат). Здесь корректно используется HAVING. - total_salary <= 700000 вместо SUM(salary) <= 700000:
✅ Это утверждение верно. В секции HAVING используется псевдоним total_salary, который недоступен на момент выполнения фильтрации. Для корректной работы нужно использовать агрегатную функцию напрямую:
sqlКопировать кодHAVING SUM(salary) <= 700000
📌Правильный ответ:
5. Используется total_salary <= 700000 вместо SUM(salary) <= 700000
Вопрос 5
Найдите данные, относящиеся только к левой таблице Orders, в таблицах Orders и Clients, учитывая, что общий столбец между ними — client_id.
- SELECT Orders.order_id FROM Orders LEFT JOIN Clients ON Clients.client_id = Orders.client_id;
- SELECT Orders.order_id FROM Orders LEFT JOIN Clients ON Clients.client_id = Orders.client_id WHERE Orders.client_id IS NOT NULL;
- SELECT Orders.order_id FROM Orders LEFT JOIN Clients ON Clients.client_id = Orders.client_id WHERE Orders.client_id IS NULL;
- SELECT Orders.order_id FROM Orders LEFT JOIN Clients ON Clients.client_id = Orders.client_id WHERE Clients.client_id IS NULL;
- SELECT Orders.order_id FROM Orders LEFT JOIN Clients ON Clients.client_id = Orders.client_id WHERE Clients.client_id IS NOT NULL;
Обоснование:
- LEFT JOIN и его особенности:
При использовании LEFT JOIN извлекаются все строки из левой таблицы (Orders), даже если нет соответствующих строк в правой таблице (Clients). Если записи отсутствуют в правой таблице, значения будут заполнены NULL. - Поиск только данных из левой таблицы:
Чтобы найти записи, которые присутствуют только в левой таблице (Orders), нужно отфильтровать строки, где Clients.client_id IS NULL. Это означает, что для этих строк нет соответствующих записей в таблице Clients. - Анализ вариантов:
Вариант 1:
Этот запрос возвращает все строки из Orders, присоединив к ним данные из Clients. Однако фильтрации данных только из левой таблицы нет.
❌ Неверно. - Вариант 2:
Условие WHERE Orders.client_id IS NOT NULL не является фильтром, определяющим, что данные относятся только к Orders.
❌ Неверно. - Вариант 3:
Условие WHERE Orders.client_id IS NULL фильтрует строки, где Orders.client_id равен NULL, а это некорректно, так как данные из таблицы Orders уже зависят от ключа client_id.
❌ Неверно. - Вариант 4:
Условие WHERE Clients.client_id IS NULL корректно определяет строки, у которых нет соответствий в таблице Clients, то есть данные относятся только к Orders.
✅ Правильно. - Вариант 5:
Условие WHERE Clients.client_id IS NOT NULL возвращает строки, которые имеют соответствия в таблице Clients, а не данные только из Orders.
❌ Неверно.
📌Правильный ответ:
4. SELECT Orders.order_id FROM Orders LEFT JOIN Clients ON Clients.client_id = Orders.client_id WHERE Clients.client_id IS NULL;
Вопрос 6
Найдите имена сотрудников, зарплата которых ниже медианной зарплаты всех сотрудников в таблице Employees.
- SELECT first_name, last_name FROM Employees WHERE (SELECT SUM(salary) / COUNT(*) FROM employees) < salary;
- SELECT first_name, last_name FROM Employees WHERE salary < AVG(salary);
- SELECT first_name, last_name FROM Employees WHERE MEDIAN(salary) < salary;
- SELECT first_name, last_name FROM Employees GROUP BY first_name, last_name HAVING salary < MEDIAN(salary);
- SELECT first_name, last_name FROM Employees WHERE salary < (SELECT MEDIAN(salary) FROM Employees);
Обоснование:
Медиана и среднее значение:
Медианная зарплата отличается от среднего значения зарплаты (AVG). Медиана делит набор данных на две равные части, тогда как AVG вычисляет среднее арифметическое. Запросы, использующие AVG, не подходят для задачи, так как они сравнивают с некорректным значением.
MEDIAN в SQL:
Некоторые SQL-системы, такие как Oracle, поддерживают функцию MEDIAN. Однако в других системах, таких как MySQL, медиана рассчитывается вручную через вложенные подзапросы или другие подходы.
Анализ вариантов:
Вариант 1:
В данном запросе используется расчет среднего значения зарплаты через SUM(salary) / COUNT(*), а не медианы. Это не соответствует задаче.
❌ Неверно.
Вариант 2:
В данном запросе сравнивается зарплата сотрудников со средним значением (AVG(salary)), что также не является медианной зарплатой.
❌ Неверно.
Вариант 3:
Используется функция MEDIAN, но в запросе сравнивается, где медиана меньше зарплаты (MEDIAN(salary) < salary), что логически некорректно.
❌ Неверно.
Вариант 4:
Используется группировка (GROUP BY), которая здесь избыточна, так как задача не требует агрегации по группам. Кроме того, синтаксис с MEDIAN в HAVING некорректен в большинстве SQL-систем.
❌ Неверно.
Вариант 5:
Этот запрос корректно определяет сотрудников с зарплатой ниже медианной, используя подзапрос для вычисления медианы:
SELECT MEDIAN(salary) FROM Employees
Затем результат сравнивается с зарплатой сотрудников.
✅ Правильно.
📌Правильный ответ:
5. SELECT first_name, last_name FROM Employees WHERE salary < (SELECT MEDIAN(salary) FROM Employees);
Вопрос 7
Вам нужно создать представление с именем PeopleView с данными из двух таблиц Respondents и Info, в котором будут содержаться возраст, телефоны и адреса респондентов. Какая ошибка допущена в запросе?
- Вместо CREATE VIEW PeopleView нужно написать CREATE PeopleView VIEW
- Нужно указывать, из каких таблиц взяты данные, т. е. Respondents.age, Respondents.phone_number, Info.address
- Перед SELECT есть AS, который не нужен
- Нужно указывать, из каких таблиц взяты данные, т. е. age.Respondents, phone_number.Respondents, address.Info
- Не нужно указывать обе таблицы в строке с FROM
Обоснование:
- Синтаксис CREATE VIEW:
Команда CREATE VIEW корректна. Сначала идет ключевое слово CREATE VIEW, затем имя представления, после чего указывается запрос, создающий содержимое представления. Вариант 1 неверен. - Неоднозначность столбцов:
В запросе используются столбцы age, phone_number и address, которые присутствуют в двух таблицах. Это вызывает неоднозначность, так как SQL не может определить, из какой таблицы брать значения. Для устранения этой проблемы необходимо явно указывать таблицу для каждого столбца, например:
SELECT Respondents.age, Respondents.phone_number, Info.address
- AS перед SELECT:
Ключевое слово AS используется для создания псевдонимов и в данном случае корректно применено для обозначения представления. Ошибка отсутствует, поэтому вариант 3 неверен. - Синтаксис с перестановкой таблиц и столбцов:
Указание age.Respondents и т. п. является неправильным синтаксисом SQL. Не существует порядка, который бы ставил столбец перед таблицей. Вариант 4 неверен. - Использование обеих таблиц в FROM:
Указание обеих таблиц в FROM корректно, поскольку требуется объединение данных. Однако для лучшей читаемости можно использовать явное объединение JOIN. Ошибка в этом нет, поэтому вариант 5 неверен.
📌Правильный ответ:
2. Нужно указывать, из каких таблиц взяты данные, т. е. Respondents.age, Respondents.phone_number, Info.address
Вопрос 8
Вы создали некластеризованный индекс в таблице Products для столбца category, который содержит его записи и адреса соответствующей строки (в основной таблице), в которой находится запись столбца. Какой шаг из перечисленных ниже не совершается при запуске следующего запроса?
Варианты ответа:
- Переход по некластеризованному индексу (product_category_index)
- Поиск в основной таблице адреса соответствующей строки, в которой находится запись столбца, и переход к этой строке в основной таблице
- Поиск искомой записи столбца (category = 'electronics') методом двоичного поиска
- Сохранение выбранных значений в дополнительной таблице
- Выбор других значений столбца в соответствии с требованиями запроса
Обоснование:
Некластеризованный индекс ускоряет поиск записей по индексу и позволяет найти адрес строки в основной таблице. Однако он не создает или сохраняет данные в дополнительной таблице. Сохранение данных в дополнительной таблице не является частью стандартного поведения индекса.
📌Правильный ответ:
4. Сохранение выбранных значений в дополнительной таблице
Вопрос 9. Вы создали таблицу:
Выберите, какая команда должна быть первой в процедуре, работающей с ошибками и транзакциями.
- SET XACT_ABORT, NOCOUNT ON
- RAISERROR <> RETURN
- BEGIN CATCH <> END CATCH
- BEGIN TRANSACTION <> COMMIT TRANSACTION
- BEGIN TRY <> END TRY
Обоснование:
Команда SET XACT_ABORT ON является важной настройкой для работы с транзакциями в SQL Server. Она гарантирует, что при возникновении ошибки транзакция автоматически откатывается. Эта команда должна быть выполнена перед началом блока транзакции (BEGIN TRY или BEGIN TRANSACTION) для обеспечения корректной работы.
📌Правильный ответ:
Вопрос 10
У вас есть таблица Orders с миллионом строк и проиндексированным столбцом order_date, который был создан с использованием следующего запроса:
Каким образом вы будете оптимизировать производительность запроса, который извлекает информацию о последнем заказе для клиента из таблицы?
- Использую запрос SELECT * и отфильтрую результаты по order_date
- Создам представление, которое извлекает последнюю информацию о заказах для всех клиентов по поиску в order_date, а затем запрашивает представление для конкретного клиента
- Использую подзапрос, чтобы получить последний order_date для клиента, а затем объединю результаты с таблицей Orders, чтобы получить полную информацию о заказе
- Добавлю дополнительные индексы в другие столбцы в таблице Orders
- Создам хранимую процедуру с вложенным циклом, которая выполняет полное сканирование таблицы и по поиску в order_date возвращает последнюю информацию о заказе для указанного клиента
Обоснование:
Использование индекса на order_date значительно ускоряет поиск, но оптимизация должна учитывать минимальное чтение данных.
Хранимые процедуры и полное сканирование таблицы (варианты с циклами) неэффективны при больших объемах данных.
Представления и подзапросы могут улучшить читаемость и повторное использование кода.
Анализ вариантов:
Вариант 1:
Использование SELECT * неэффективно, так как извлекаются все столбцы, что увеличивает объем данных. Фильтрация по order_date будет работать быстрее благодаря индексу, но это не оптимальный подход для конкретного клиента.
❌ Неверно.
Вариант 2:
Создание представления, которое извлекает последнюю информацию о заказах, улучшает читаемость и упрощает повторное использование. Однако оно может быть избыточным, если цель состоит в извлечении данных только для одного клиента.
❌ Неверно.
Вариант 3:
Использование подзапроса позволяет эффективно получить последний order_date для клиента, а затем с помощью объединения извлечь дополнительные данные. Индекс на order_date обеспечивает минимальное чтение данных. Это лучший способ оптимизации.
✅ Правильно.
Вариант 4:
Добавление дополнительных индексов может ускорить другие запросы, но не обязательно улучшит производительность данного запроса.
❌ Неверно.
Вариант 5:
Создание хранимой процедуры с вложенным циклом и полным сканированием таблицы неэффективно для больших таблиц, так как увеличивает затраты на обработку.
❌ Неверно.
📌Правильный ответ:
3. Использую подзапрос, чтобы получить последний order_date для клиента, а затем объединю результаты с таблицей Orders, чтобы получить полную информацию о заказе
Вопрос 11
Напишите SQL-запрос, который выберет все записи из таблицы Customers, у которых имя (name) начинается на букву "A" или "M", и возраст (age) больше 25 лет. Отсортируйте список в порядке убывания возраста.
- SELECT * FROM Customers WHERE (name LIKE 'A' OR name LIKE 'M') AND age > 25 ORDER BY age ASC
- SELECT * FROM Customers WHERE (name = 'A' OR name = 'M') AND age > 25 ORDER BY age DESC
- SELECT * FROM Customers WHERE (name LIKE 'A%' AND name LIKE 'M%') AND age > 25
- SELECT * FROM Customers WHERE (name LIKE 'A%' OR name LIKE 'M%') AND age > 25 ORDER BY age DESC
- SELECT * FROM Customers WHERE (name = 'A' AND name = 'M') AND age > 25 ORDER BY age ASC
Обоснование:
Разбор условий: Имя должно начинаться с буквы "A" или "M", что можно задать с помощью LIKE 'A%' или LIKE 'M%'.
Возраст должен быть больше 25 (age > 25).
Сортировка должна быть в порядке убывания возраста (ORDER BY age DESC).
Анализ вариантов:
Вариант 1:
Условие name LIKE 'A' OR name LIKE 'M' проверяет, совпадает ли имя с одной буквой, а не с начальной буквой. Также указана сортировка ASC (по возрастанию), что не соответствует условию задачи.
❌ Неверно.
Вариант 2:
Условие name = 'A' OR name = 'M' проверяет, полностью ли имя равно "A" или "M". Это не соответствует условию поиска имен, начинающихся с "A" или "M".
❌ Неверно.
Вариант 3:
Условие name LIKE 'A%' AND name LIKE 'M%' одновременно требует, чтобы имя начиналось и с "A", и с "M", что невозможно.
❌ Неверно.
Вариант 4:
Условие name LIKE 'A%' OR name LIKE 'M%' правильно проверяет, начинается ли имя с "A" или "M". Также указана правильная сортировка ORDER BY age DESC.
✅ Правильно.
Вариант 5:
Условие name = 'A' AND name = 'M' одновременно требует, чтобы имя было равно "A" и "M", что невозможно.
❌ Неверно.
📌Правильный ответ:
4. SELECT * FROM Customers WHERE (name LIKE 'A%' OR name LIKE 'M%') AND age > 25 ORDER BY age DESC
Вопрос 12
Вы даете разрешение или запрет на выполнение определенных операций над объектами базы данных компании. Какие операторы вы используете в данном процессе?
Обоснование:
GRANT, REVOKE:
Эти операторы используются для управления доступом и правами пользователей к объектам базы данных:GRANT предоставляет разрешения.
REVOKE отбирает ранее предоставленные разрешения.
Эти операторы прямо относятся к процессу управления разрешениями.
✅ Правильно.
INSERT INTO, UPDATE:
Эти операторы используются для внесения изменений в данные таблиц, но они не связаны с предоставлением или запретом прав.
❌ Неверно.
REPLACE, CALL:
Эти операторы используются для работы с процедурами или замены записей, но не для управления разрешениями.
❌ Неверно.
COMMIT, ROLLBACK:
Эти операторы управляют транзакциями (подтверждают или отменяют их), но не регулируют доступ к объектам базы данных.
❌ Неверно.
ALTER, DROP:
Эти операторы управляют структурой объектов базы данных (изменение или удаление), но не используются для предоставления или ограничения прав доступа.
❌ Неверно.
📌Правильный ответ:
Вопрос 13. Какую задачу может решать данный код?
- Получение информации о дорогих и дешевых товарах, где дорогими считаются товары дороже 100 рублей. При этом отобразится сначала список дорогих товаров, затем список дешевых.
- Получение информации о дорогих и дешевых товарах, где дорогими считаются товары с ценой выше 100 рублей. При этом отобразится название товара и его цена.
- Получение информации о цене товара. В результате исполнения кода цена будет отсортирована по убыванию, если цена будет выше 100, у товара будет метка expensive, если дешевле, то cheap.
- Получение данных о дорогих и дешевых товарах, где дорогими считаются товары дороже 100 рублей. При этом отобразится таблица с названием товаров в одном столбике и указанием дорогой он или дешевый в другом.
- Получение информации о дорогих и дешевых товарах, где дорогими считаются товары дороже 100 рублей. При этом отобразится только список дорогих товаров.
Обоснование:
Этот запрос создает новый столбец product_cost, который содержит метки 'expensive' или 'cheap' в зависимости от условия CASE. Название товара отображается в столбце product_name. Код не сортирует данные, так как отсутствует ORDER BY.
Анализ вариантов:
Вариант 1:
Код не выполняет сортировку, так как ORDER BY отсутствует. Вывод данных дорогих и дешевых товаров в заданном порядке невозможен.
❌ Неверно.
Вариант 2:
Код не отображает цену товара (price) — только название и метку (expensive или cheap).
❌ Неверно.
Вариант 3:
Код не сортирует данные, так как отсутствует команда ORDER BY. Вывод данных по убыванию цены невозможен.
❌ Неверно.
Вариант 4:
Код формирует таблицу, в которой один столбец содержит название товара, а другой — метку (expensive или cheap). Это соответствует результату выполнения запроса.
✅ Правильно.
Вариант 5:
Код не ограничивает выборку только дорогими товарами, так как отсутствует условие фильтрации WHERE price > 100.
❌ Неверно.
📌Правильный ответ:
4. Получение данных о дорогих и дешевых товарах, где дорогими считаются товары дороже 100 рублей. При этом отобразится таблица с названием товаров в одном столбике и указанием дорогой он или дешевый в другом.
Вопрос 14:
Текст вопроса:
Вам нужен отсортированный в алфавитном порядке список из 10 неповторяющихся имён в таблице group_A. С помощью какого кода может быть решена данная задача?
- SELECT surname FROM group_A ORDER BY surname LIMIT 10;
- SELECT surname FROM group_A SORT BY surname DESC LIMIT 10;
- SELECT DISTINCT surname FROM group_A ORDER BY surname LIMIT 10;
- SELECTsurname FROM group_A ORDER BY surname LIMIT 10;
- SELECT DISTINCT surname FROM group_A GROUP BY surname LIMIT 11;
Обоснование:
Нужно выбрать 10 записей, которые:
- Содержат уникальные значения (DISTINCT).
- Отсортированы в алфавитном порядке (ORDER BY surname).
- Условие: LIMIT 10 обеспечивает выборку первых 10 строк.
Анализ вариантов:
Вариант 1: Отбираются все значения surname без исключения повторяющихся. Это не соответствует задаче, так как не применен DISTINCT.
❌ Неверно.
Вариант 2: Используется некорректная команда SORT BY, которая не поддерживается SQL. Вместо нее должно быть ORDER BY.
❌ Неверно.
Вариант 3: Используется правильное сочетание:SELECT DISTINCT surname исключает дубликаты.
ORDER BY surname сортирует записи в алфавитном порядке.
LIMIT 10 ограничивает выборку первыми 10 строками.
✅ Правильно.
Вариант 4: Синтаксическая ошибка: отсутствует пробел между SELECT и surname.
❌ Неверно.
Вариант 5: Указано GROUP BY surname, что избыточно при использовании DISTINCT. Кроме того, указано LIMIT 11, что не соответствует задаче, где требуется 10 строк.
❌ Неверно.
📌Правильный ответ:
3. SELECT DISTINCT surname FROM group_A ORDER BY surname LIMIT 10;
Вопрос 15
У вас есть две таблицы: workers и salary. Первая таблица содержит уникальный id сотрудника, его фамилию (surname) и должность (position). Во второй таблице указано: id должности, сама должность и соответствующая ей зарплата.
Вам нужно узнать, сколько зарабатывает каждый сотрудник. Какой вариант кода сможет решить данную задачу?
- SELECT workers FROM workers JOIN salary s ON w.position = s.position;
- SELECT * FROM workers w JOIN salary s ON w.position = s.position ORDER BY surname LIMIT 10;
- SELECT * FROM workers w LEFT JOIN salary s ON w.position = s.position GROUP BY position ORDER BY surname;
- SELECT position FROM workers w LEFT JOIN salary s ON w.position = s.position;
- SELECT * FROM workers w JOIN salary s ON w.position = s.position;
Обоснование:
Чтобы получить зарплату для каждого сотрудника, нужно соединить таблицы workers и salary по столбцу position.Это выполняется с помощью JOIN.
Для получения полной информации о сотрудниках и их зарплате нужно выбрать все необходимые столбцы из обеих таблиц.
Анализ вариантов:
Вариант 1:
Некорректный синтаксис: SELECT workers не является допустимым запросом, так как таблица целиком не может быть указана без столбцов.
❌ Неверно.
Вариант 2:
Этот запрос выполняет соединение таблиц с помощью JOIN и сортирует данные по фамилии сотрудников (ORDER BY surname). LIMIT 10 ограничивает вывод до первых 10 записей, что соответствует частичному решению задачи. Однако это ограничение может не отображать всех сотрудников.
🤔 Подходит, но ограничивает вывод.
Вариант 3:
Используется LEFT JOIN, который возвращает все строки из таблицы workers и соответствующие записи из таблицы salary. Указано GROUP BY, что избыточно и не требуется, так как данные уже однозначно связаны через JOIN.
❌ Неверно.
Вариант 4:
Запрос выбирает только столбец position, не включая фамилии и зарплаты сотрудников. Это не решает задачу полностью.
❌ Неверно.
Вариант 5:
Запрос выполняет правильное соединение таблиц с помощью JOIN для получения всех данных о сотрудниках и их зарплатах. Это решает задачу полностью.
✅ Правильно.
📌Правильный ответ:
5. SELECT * FROM workers w JOIN salary s ON w.position = s.position;
Заключение
Отличная работа! Вы успешно прошли через сложные задания и подтвердили свой высокий уровень знаний SQL. Способность работать с продвинутыми конструкциями, сложными объединениями таблиц и оптимизацией запросов подчеркивает вашу экспертизу в управлении данными. После успешного прохождения теста на продвинутый уровень на платформе HeadHunter, вы сможете уверенно заявить о своих навыках и претендовать на самые амбициозные проекты и роли.
P.S.
Дорогие читатели! Если материалы данной статьи помогли вам успешно пройти тест, буду признателен, если вы поставите лайк 👍🏻 именно той статье, которая соответствовала вашему уровню подготовки. Также, если тестирование оказалось неудачным ❌, пожалуйста, оставьте комментарий 📝 с указанием количества ошибок допущенных в тесте.
Эта обратная связь чрезвычайно важна. Она позволит в дальнейшем проанализировать эффективность материалов, а также создать аналитическое заключение для всей серии статей по прохождению тестирования на платформе. Спасибо за вашу помощь в совершенствовании контента!