MySQL SELECT: полное руководство от базовых запросов до JOIN

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Новички в 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;

В этом запросе:

  1. Сначала отбираются сотрудники с зарплатой выше 50000 (WHERE)
  2. Затем они группируются по отделам (GROUP BY)
  3. Отбираются только группы со средней зарплатой выше 80000 (HAVING)
  4. Результаты сортируются по убыванию средней зарплаты (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
);

Этот запрос находит сотрудников с зарплатой выше средней в их отделе.

Оптимизация сложных запросов

При работе со сложными запросами важно помнить об их оптимизации:

  1. Избегайте использования SELECT * в производственном коде, запрашивайте только нужные столбцы
  2. Используйте соответствующие индексы для столбцов, часто используемых в WHERE и JOIN
  3. Ограничивайте количество строк с помощью LIMIT, особенно для больших таблиц
  4. Используйте EXPLAIN перед запросом, чтобы увидеть план его выполнения и найти узкие места
  5. Рассмотрите возможность использования временных таблиц или представлений для сложных промежуточных результатов

Пример использования 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 — это только начало вашего путешествия в мир баз данных. Понимание того, как эффективно извлекать, фильтровать и обрабатывать информацию, открывает множество возможностей для анализа данных и принятия обоснованных решений. Начните с простых запросов, постепенно добавляя более сложные конструкции, и вскоре вы сможете создавать точные, оптимизированные запросы для решения любых задач, связанных с данными. Помните: практика и эксперименты с различными комбинациями операторов — лучший способ закрепить полученные знания.

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какой оператор используется для фильтрации данных в запросах SQL?
1 / 5

Загрузка...