MySQL SELECT: полное руководство от базовых запросов до JOIN
Для кого эта статья:
- Новички в SQL и MySQL, желающие освоить основу работы с базами данных
- Специалисты, стремящиеся улучшить свои навыки анализа данных через SQL
Люди, интересующиеся курсами и образовательными ресурсами по SQL и аналитике данных
Команда SELECT — это сердце любого взаимодействия с базой данных MySQL. 🚀 Без неё невозможно извлечь ни одну строку данных, проанализировать результаты или построить отчёты. Владение этой командой отличает новичка от профессионала, и часто становится тем навыком, который открывает двери в мир работы с данными. Независимо от того, делаете ли вы первые шаги в SQL или хотите структурировать свои знания — это руководство проведёт вас от простейших запросов до сложных конструкций с примерами, которые вы сможете применить немедленно.
Хотите не просто читать о SQL, а получить структурированные знания под руководством практикующих экспертов? Обучение SQL с нуля от Skypro — это интерактивные занятия с разбором реальных кейсов и практических задач по MySQL. Вместо сухой теории вас ждут живые проекты, где команда SELECT станет вашим надёжным инструментом для решения аналитических задач. Бонус для читателей статьи — доступ к расширенной библиотеке запросов после регистрации!
Основы и синтаксис SELECT в MySQL для начинающих
Команда SELECT в MySQL — это основной инструмент для извлечения данных из базы. Представьте её как своеобразный фильтр, который позволяет "зачерпнуть" нужную информацию из огромного массива данных. Базовый синтаксис команды выглядит следующим образом:
SELECT column1, column2, ...
FROM table_name;
Где column1, column2 — имена столбцов, данные из которых вы хотите получить, а table_name — название таблицы, в которой эти столбцы находятся.
Если вам нужны все столбцы таблицы, можно использовать символ звездочки:
SELECT * FROM table_name;
Однако опытные разработчики не рекомендуют использовать "*" в производственном коде по нескольким причинам:
- Это увеличивает нагрузку на сеть и сервер
- Может снизить производительность запроса
- Делает код менее понятным и предсказуемым
- При изменении структуры таблицы может привести к неожиданным результатам
Рассмотрим простой пример. Допустим, у нас есть таблица employees с данными о сотрудниках компании:
| id | name | position | salary | department |
|---|---|---|---|---|
| 1 | Иван Петров | Разработчик | 90000 | IT |
| 2 | Анна Иванова | Аналитик | 85000 | Аналитика |
| 3 | Сергей Сидоров | Менеджер | 120000 | Продажи |
Чтобы получить только имена и должности сотрудников, мы можем выполнить следующий запрос:
SELECT name, position FROM employees;
Результатом будет:
| name | position |
|---|---|
| Иван Петров | Разработчик |
| Анна Иванова | Аналитик |
| Сергей Сидоров | Менеджер |
Для улучшения читаемости результатов можно использовать псевдонимы (aliases) для столбцов:
SELECT name AS 'Имя сотрудника', position AS 'Должность'
FROM employees;
В этом случае заголовки столбцов в результате будут отображаться как "Имя сотрудника" и "Должность" вместо оригинальных названий.
Кроме того, вы можете выполнять вычисления непосредственно в SELECT-запросе:
SELECT name, salary, salary * 0.13 AS tax
FROM employees;
Этот запрос вернёт имя сотрудника, его зарплату и рассчитанный налог (13% от зарплаты).
Алексей Комаров, преподаватель SQL
Когда я только начинал осваивать MySQL, мне было сложно понять, зачем нужно выбирать конкретные столбцы вместо использования звёздочки. На одном из проектов мы работали с таблицей клиентов, содержащей более 50 столбцов и миллионы строк. Мой коллега написал простой скрипт, который запрашивал все данные с помощью SELECT * и затем обрабатывал их в приложении.
Всё работало нормально, пока база не выросла до критического размера. Однажды утром мы получили сообщения об ошибках таймаута от пользователей. Выяснилось, что запрос с SELECT * занимал слишком много времени и ресурсов. Мы переписали запрос, выбирая только 5 необходимых столбцов, и время выполнения сократилось в 7 раз! Этот случай стал для меня наглядным уроком о том, как важно запрашивать только те данные, которые действительно нужны.

SELECT с условиями: применение WHERE для фильтрации
В реальных задачах часто требуется получить не все строки таблицы, а только те, которые соответствуют определённым критериям. Для этого используется оператор WHERE, который позволяет задать условия фильтрации данных. 🔍
Базовый синтаксис запроса с условием:
SELECT column1, column2, ...
FROM table_name
WHERE condition;
Где condition — это логическое выражение, которое должно быть истинным для выбираемых строк.
Рассмотрим основные операторы сравнения, используемые в условиях WHERE:
| Оператор | Описание | Пример |
|---|---|---|
| = | Равно | WHERE salary = 90000 |
| > | Больше чем | WHERE salary > 80000 |
| < | Меньше чем | WHERE salary < 100000 |
| >= | Больше или равно | WHERE salary >= 90000 |
| <= | Меньше или равно | WHERE salary <= 90000 |
| !=, <> | Не равно | WHERE department != 'IT' |
| BETWEEN | Между значениями | WHERE salary BETWEEN 80000 AND 100000 |
| LIKE | Соответствие шаблону | WHERE name LIKE 'Ив%' |
| IN | Одно из перечисленных значений | WHERE department IN ('IT', 'Продажи') |
| IS NULL | Значение NULL | WHERE manager_id IS NULL |
Условия можно комбинировать с помощью логических операторов AND и OR:
SELECT * FROM employees
WHERE department = 'IT' AND salary > 80000;
Этот запрос вернёт всех сотрудников из отдела IT с зарплатой выше 80000.
Если нам нужно получить сотрудников либо из IT-отдела, либо с зарплатой выше 100000:
SELECT * FROM employees
WHERE department = 'IT' OR salary > 100000;
Для более сложных условий можно использовать скобки для группировки выражений:
SELECT * FROM employees
WHERE (department = 'IT' OR department = 'Аналитика')
AND salary > 85000;
Оператор LIKE используется для поиска по шаблону в текстовых полях, где:
%– заменяет любое количество символов (включая ноль)_– заменяет ровно один символ
Например, найти всех сотрудников, чьи имена начинаются с "А":
SELECT * FROM employees
WHERE name LIKE 'А%';
Оператор IN позволяет проверить, соответствует ли значение любому из перечисленных в списке:
SELECT * FROM employees
WHERE department IN ('IT', 'Аналитика', 'Маркетинг');
Для работы с NULL-значениями используются специальные операторы IS NULL и IS NOT NULL:
SELECT * FROM employees
WHERE manager_id IS NULL;
Такой запрос найдёт всех сотрудников, у которых не назначен менеджер.
Для отрицания условия используется оператор NOT:
SELECT * FROM employees
WHERE NOT department = 'IT';
или
SELECT * FROM employees
WHERE department <> 'IT';
Оба запроса найдут всех сотрудников, не относящихся к IT-отделу.
Сортировка и группировка данных при работе с SELECT
После извлечения данных часто требуется их упорядочить определённым образом или объединить схожие записи в группы для последующего анализа. MySQL предоставляет для этого операторы ORDER BY и GROUP BY. 📊
Сортировка с помощью ORDER BY
Оператор ORDER BY позволяет упорядочить результаты запроса по значениям одного или нескольких столбцов:
SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...;
Где:
- ASC – сортировка по возрастанию (используется по умолчанию)
- DESC – сортировка по убыванию
Например, чтобы отсортировать сотрудников по размеру зарплаты от высшей к низшей:
SELECT name, position, salary
FROM employees
ORDER BY salary DESC;
Можно сортировать по нескольким столбцам. В этом случае сначала данные сортируются по первому указанному столбцу, затем внутри каждой группы с одинаковым значением первого столбца – по второму и т.д.
SELECT name, department, salary
FROM employees
ORDER BY department ASC, salary DESC;
Этот запрос сначала сгруппирует сотрудников по отделам в алфавитном порядке, а затем в каждом отделе отсортирует их по убыванию зарплаты.
Также можно сортировать по столбцам, которые не включены в результат запроса:
SELECT name, position
FROM employees
ORDER BY salary DESC;
Группировка с помощью GROUP BY
Оператор GROUP BY позволяет объединить строки с одинаковыми значениями в указанных столбцах в группы. Это особенно полезно при использовании агрегатных функций:
- COUNT() – подсчитывает количество строк
- SUM() – суммирует значения
- AVG() – вычисляет среднее арифметическое
- MIN() – находит минимальное значение
- MAX() – находит максимальное значение
Базовый синтаксис:
SELECT column1, column2, ..., aggregate_function(column)
FROM table_name
GROUP BY column1, column2, ...;
Например, чтобы узнать количество сотрудников в каждом отделе:
SELECT department, COUNT(*) AS 'Количество сотрудников'
FROM employees
GROUP BY department;
Результат может выглядеть так:
| department | Количество сотрудников |
|---|---|
| IT | 15 |
| Аналитика | 8 |
| Продажи | 12 |
| Маркетинг | 6 |
Можно использовать несколько агрегатных функций в одном запросе:
SELECT department,
COUNT(*) AS 'Количество сотрудников',
AVG(salary) AS 'Средняя зарплата',
MAX(salary) AS 'Максимальная зарплата',
MIN(salary) AS 'Минимальная зарплата'
FROM employees
GROUP BY department;
Чтобы фильтровать группы по результатам агрегатных функций, используется оператор HAVING (он работает с группами, тогда как WHERE работает с отдельными строками):
SELECT department, COUNT(*) AS 'Количество сотрудников'
FROM employees
GROUP BY department
HAVING COUNT(*) > 10;
Этот запрос покажет только отделы, где работает более 10 сотрудников.
Порядок применения операторов в запросе имеет значение:
SELECT department, AVG(salary) AS 'Средняя зарплата'
FROM employees
WHERE salary > 50000
GROUP BY department
HAVING AVG(salary) > 80000
ORDER BY AVG(salary) DESC;
В этом запросе:
- Сначала отбираются сотрудники с зарплатой выше 50000 (WHERE)
- Затем они группируются по отделам (GROUP BY)
- Отбираются только группы со средней зарплатой выше 80000 (HAVING)
- Результаты сортируются по убыванию средней зарплаты (ORDER BY)
Мария Савельева, аналитик данных
В одном из моих первых проектов по анализу продаж интернет-магазина передо мной стояла задача выявить самые прибыльные категории товаров по регионам. База данных содержала миллионы записей о продажах, и без правильного использования GROUP BY я бы просто утонула в данных.
Начала я с простого: SELECT category, SUM(revenue) FROM sales GROUP BY category. Получила общую выручку по категориям, но этого было недостаточно. Когда я добавила в группировку поле region (SELECT region, category, SUM(revenue) FROM sales GROUP BY region, category), результаты стали намного информативнее.
Настоящий прорыв произошёл, когда я применила HAVING для фильтрации групп: я отсеяла регионы с малым количеством заказов, чтобы исключить статистические выбросы. После сортировки результатов с помощью ORDER BY мы смогли точно определить, на каких категориях товаров и в каких регионах нужно сфокусировать маркетинговые усилия. Это привело к росту продаж на 28% в следующем квартале. Тогда я поняла, что правильная группировка данных — это не просто технический приём, а мощный инструмент для принятия бизнес-решений.
Объединение таблиц: JOIN-запросы в MySQL
В реляционных базах данных информация часто распределяется по нескольким таблицам для минимизации дублирования и повышения эффективности. Операторы JOIN позволяют объединять данные из разных таблиц в единый результирующий набор. 🔄
Существует несколько типов JOIN-операций:
- INNER JOIN – возвращает строки, для которых есть соответствия в обеих таблицах
- LEFT JOIN (или LEFT OUTER JOIN) – возвращает все строки из левой таблицы и соответствующие строки из правой
- RIGHT JOIN (или RIGHT OUTER JOIN) – возвращает все строки из правой таблицы и соответствующие строки из левой
- FULL JOIN (или FULL OUTER JOIN) – возвращает строки, когда есть соответствие в одной из таблиц (в MySQL напрямую не поддерживается, но может быть эмулирован)
- CROSS JOIN – возвращает декартово произведение двух таблиц
Рассмотрим пример с двумя таблицами: employees (сотрудники) и departments (отделы):
Таблица employees:
| id | name | position | salary | department_id |
|---|---|---|---|---|
| 1 | Иван Петров | Разработчик | 90000 | 1 |
| 2 | Анна Иванова | Аналитик | 85000 | 2 |
| 3 | Сергей Сидоров | Менеджер | 120000 | 3 |
| 4 | Елена Козлова | Дизайнер | 75000 | 4 |
Таблица departments:
| id | name | location |
|---|---|---|
| 1 | IT | Москва |
| 2 | Аналитика | Санкт-Петербург |
| 3 | Продажи | Москва |
| 5 | HR | Казань |
INNER JOIN
INNER JOIN возвращает только строки, у которых есть совпадения в обеих таблицах:
SELECT e.name, e.position, d.name AS department, d.location
FROM employees e
INNER JOIN departments d ON e.department_id = d.id;
Результат будет содержать только сотрудников, для которых найден соответствующий отдел:
| name | position | department | location |
|---|---|---|---|
| Иван Петров | Разработчик | IT | Москва |
| Анна Иванова | Аналитик | Аналитика | Санкт-Петербург |
| Сергей Сидоров | Менеджер | Продажи | Москва |
Обратите внимание, что Елена Козлова не попала в результат, так как в таблице departments нет отдела с id=4.
LEFT JOIN
LEFT JOIN возвращает все строки из левой таблицы (employees) и соответствующие строки из правой (departments). Если соответствия нет, в полях правой таблицы будет NULL:
SELECT e.name, e.position, d.name AS department, d.location
FROM employees e
LEFT JOIN departments d ON e.department_id = d.id;
Результат:
| name | position | department | location |
|---|---|---|---|
| Иван Петров | Разработчик | IT | Москва |
| Анна Иванова | Аналитик | Аналитика | Санкт-Петербург |
| Сергей Сидоров | Менеджер | Продажи | Москва |
| Елена Козлова | Дизайнер | NULL | NULL |
RIGHT JOIN
RIGHT JOIN работает аналогично LEFT JOIN, но возвращает все строки из правой таблицы:
SELECT e.name, e.position, d.name AS department, d.location
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.id;
Результат будет включать все отделы, даже те, где нет сотрудников:
| name | position | department | location |
|---|---|---|---|
| Иван Петров | Разработчик | IT | Москва |
| Анна Иванова | Аналитик | Аналитика | Санкт-Петербург |
| Сергей Сидоров | Менеджер | Продажи | Москва |
| NULL | NULL | HR | Казань |
Множественные JOIN-операции
В сложных запросах можно использовать несколько JOIN-операций для объединения более двух таблиц:
SELECT e.name, e.position, d.name AS department, p.name AS project
FROM employees e
INNER JOIN departments d ON e.department_id = d.id
LEFT JOIN employee_projects ep ON e.id = ep.employee_id
LEFT JOIN projects p ON ep.project_id = p.id;
Этот запрос объединяет информацию о сотрудниках, их отделах и проектах, в которых они участвуют.
Использование JOIN с другими операторами
JOIN-операции можно комбинировать с WHERE, GROUP BY, HAVING и ORDER BY для создания сложных аналитических запросов:
SELECT d.name AS department, COUNT(e.id) AS employees_count,
AVG(e.salary) AS avg_salary
FROM departments d
LEFT JOIN employees e ON d.id = e.department_id
GROUP BY d.name
HAVING COUNT(e.id) > 0
ORDER BY avg_salary DESC;
Этот запрос возвращает список отделов с количеством сотрудников и средней зарплатой, отсортированный по убыванию средней зарплаты и включающий только отделы с сотрудниками.
Расширенные функции SELECT для эффективной выборки
MySQL предлагает множество встроенных функций, которые существенно расширяют возможности SELECT-запросов и позволяют более эффективно манипулировать данными прямо в запросе. 💡
Строковые функции
Функции для работы со строковыми данными особенно полезны при обработке текстовых полей:
- CONCAT(str1, str2, ...) – объединяет строки
- SUBSTRING(str, pos, len) – извлекает подстроку
- UPPER(str) – преобразует строку в верхний регистр
- LOWER(str) – преобразует строку в нижний регистр
- TRIM(str) – удаляет пробелы в начале и конце строки
- LENGTH(str) – возвращает длину строки
- REPLACE(str, fromstr, tostr) – заменяет все вхождения fromstr на tostr
Примеры использования:
SELECT name,
CONCAT(UPPER(SUBSTRING(name, 1, 1)), LOWER(SUBSTRING(name, 2))) AS formatted_name,
LENGTH(name) AS name_length
FROM employees;
Этот запрос форматирует имена сотрудников (первая буква заглавная, остальные строчные) и показывает длину каждого имени.
Числовые функции
Для обработки числовых данных используются следующие функции:
- ROUND(num, decimal_places) – округляет число до указанного количества знаков после запятой
- FLOOR(num) – округляет число вниз до ближайшего целого
- CEILING(num) – округляет число вверх до ближайшего целого
- ABS(num) – возвращает абсолютное значение числа
- POW(x, y) – возводит x в степень y
- SQRT(num) – возвращает квадратный корень числа
Пример:
SELECT name, salary,
ROUND(salary / 12, 2) AS monthly_salary,
CEILING(salary * 0.13) AS tax
FROM employees;
Функции даты и времени
Работа с датами и временем часто требуется в аналитических запросах:
- NOW() – возвращает текущую дату и время
- CURDATE() – возвращает текущую дату
- YEAR(date), MONTH(date), DAY(date) – извлекают соответствующую часть даты
- DATEDIFF(date1, date2) – возвращает разницу в днях между двумя датами
- DATE_ADD(date, INTERVAL expr unit) – добавляет интервал к дате
- DATE_FORMAT(date, format) – форматирует дату по указанному шаблону
Пример:
SELECT name, hire_date,
DATEDIFF(CURDATE(), hire_date) AS days_employed,
DATE_FORMAT(hire_date, '%d.%m.%Y') AS formatted_date,
DATE_ADD(hire_date, INTERVAL 1 YEAR) AS anniversary
FROM employees;
Условные выражения
Функции CASE и IF позволяют создавать условные выражения в запросах:
SELECT name, salary,
CASE
WHEN salary < 50000 THEN 'Низкая'
WHEN salary BETWEEN 50000 AND 100000 THEN 'Средняя'
ELSE 'Высокая'
END AS salary_category,
IF(department_id = 1, 'IT-специалист', 'Не IT') AS specialization
FROM employees;
Подзапросы и коррелированные подзапросы
Подзапросы (запросы внутри запроса) расширяют возможности SQL, позволяя использовать результаты одного запроса в другом:
SELECT name, position, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
Этот запрос находит сотрудников с зарплатой выше средней.
Коррелированные подзапросы ссылаются на таблицы из внешнего запроса:
SELECT e1.name, e1.department_id, e1.salary
FROM employees e1
WHERE e1.salary > (
SELECT AVG(e2.salary)
FROM employees e2
WHERE e2.department_id = e1.department_id
);
Этот запрос находит сотрудников с зарплатой выше средней в их отделе.
Оптимизация сложных запросов
При работе со сложными запросами важно помнить об их оптимизации:
- Избегайте использования SELECT * в производственном коде, запрашивайте только нужные столбцы
- Используйте соответствующие индексы для столбцов, часто используемых в WHERE и JOIN
- Ограничивайте количество строк с помощью LIMIT, особенно для больших таблиц
- Используйте EXPLAIN перед запросом, чтобы увидеть план его выполнения и найти узкие места
- Рассмотрите возможность использования временных таблиц или представлений для сложных промежуточных результатов
Пример использования LIMIT для ограничения результатов:
SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5;
Этот запрос возвращает пять сотрудников с самыми высокими зарплатами.
Для постраничного вывода можно использовать комбинацию LIMIT и OFFSET:
SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 10 OFFSET 20;
Этот запрос пропускает первые 20 результатов и возвращает следующие 10, что удобно для реализации постраничной навигации.
Овладение командой SELECT в MySQL — это только начало вашего путешествия в мир баз данных. Понимание того, как эффективно извлекать, фильтровать и обрабатывать информацию, открывает множество возможностей для анализа данных и принятия обоснованных решений. Начните с простых запросов, постепенно добавляя более сложные конструкции, и вскоре вы сможете создавать точные, оптимизированные запросы для решения любых задач, связанных с данными. Помните: практика и эксперименты с различными комбинациями операторов — лучший способ закрепить полученные знания.
Читайте также
- Визуализация данных в Python: Seaborn от базовых до продвинутых техник
- Топ-5 библиотек Python для анализа данных: выбор специалистов
- Пошаговая инструкция создания Telegram-бота на Python: от идеи до запуска
- Топ-5 NLP-библиотек Python: инструменты анализа естественного языка
- Установка и настройка Scikit-learn: руководство для Python-разработчиков
- Решающие деревья в Python: метод, реализация, практика, примеры
- Компьютерное зрение на Python: технологии распознавания образов
- Метрики качества ML-моделей: выбор, применение, интерпретация
- Обратное распространение ошибки в нейронных сетях: принцип работы
- Python для анализа данных: почему большинство аналитиков выбирают его