Вложенный запрос

Общая структура вложенного запроса


SELECT
  внешнее_поле,
  АГРЕГАТНАЯ_ФУНКЦИЯ(внутреннее_поле) AS агрегат
FROM (
  SELECT
    поле1,
    поле2
  FROM таблица
  WHERE условие_фильтрации
) AS имя_подзапроса
JOIN другая_таблица ON условие_связи
GROUP BY внешнее_поле
ORDER BY агрегат DESC
LIMIT 1;
        

Пример вложенного запроса


use kwalik_notarial;

select s.name_service, sum(cost) as total
from (
    select id_s, cost
    from deal
    where deal_data >= date_sub(curdate(), interval 1 year)
) as f_deal
join service s on f_deal.id_s = s.id_s
group by s.name_service
order by total desc
limit 1;
        

Как запустить и проверить запрос

Пример:

select s.name_service, sum(cost) as total
from (
    select id_s, cost
    from deal
    where deal_data >= date_sub(curdate(), interval 1 year)
) as f_deal
join service s on f_deal.id_s = s.id_s
group by s.name_service
order by total desc
limit 1;
  • deal_data >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR): фильтр по дате — только за последний год.
  • SUM(cost): сумма стоимости всех сделок.
  • LIMIT 1: выводит самую прибыльную услугу.

Объяснение ключевых частей

  1. Подзапрос (f_deal)

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

    
    -- Подзапрос: выбираем данные только за последний год
    SELECT id_s, cost
    FROM deal
    WHERE deal_data >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR);
              
  2. JOIN

    Соединяет результаты подзапроса с основной таблицей service через поле id_s.

    JOIN service s ON f_deal.id_s = s.id_s;
  3. GROUP BY

    Группирует записи по названию услуги (s.name_service) для дальнейшего агрегирования.

    GROUP BY s.name_service;
  4. SUM(cost)

    Вычисляет общую сумму стоимости сделок за последний год по каждой группе.

    SUM(f_deal.cost) AS total;
  5. ORDER BY ... DESC

    Сортирует результаты по убыванию суммы.

    ORDER BY total DESC;
  6. LIMIT 1

    Выбирает только одну запись — самую прибыльную услугу.

    LIMIT 1;

Зачем использовать вложенные запросы?

  • Для фильтрации данных перед обработкой
    Например, выбрать только те сделки, которые произошли за последние 12 месяцев.
  • Для сложных агрегаций
    Можно группировать и суммировать данные, используя предварительно отфильтрованные значения.
  • Для работы с несколькими условиями
    Если нужно выполнить несколько операций над данными, вложенные запросы помогают разбить задачу на этапы.
  • Для избежания дублирования кода
    Вложенный запрос позволяет не повторять одно и то же условие в нескольких местах.

Частые ошибки и решения

Ошибка Причина Решение
Error 1064 Неправильный синтаксис Проверьте, правильно ли закрыты скобки и ключевые слова, особенно AS, FROM, JOIN, LIMIT
Error 1146 Таблица не существует Проверьте наличие таблиц deal и service в БД
Error 1054 Неизвестное поле Проверьте, что поля id_s, cost, deal_data существуют в таблице deal
Wrong syntax near LIMIT Опечатка или неверное расположение LIMIT Убедитесь, что LIMIT стоит в конце запроса

Как протестировать запрос

  1. Шаг 1: Убедитесь, что таблицы существуют
    DESCRIBE deal;

    Проверьте, есть ли поля id_s, cost, deal_data

  2. Шаг 2: Запустите подзапрос отдельно
    
    SELECT id_s, cost
    FROM deal
    WHERE deal_data >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR);
              

    Это поможет понять, какие данные выдает подзапрос

  3. Шаг 3: Запустите полный запрос
    
    SELECT s.name_service, SUM(f_deal.cost) AS total
    FROM (
      SELECT id_s, cost
      FROM deal
      WHERE deal_data >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
    ) AS f_deal
    JOIN service s ON f_deal.id_s = s.id_s
    GROUP BY s.name_service
    ORDER BY total DESC
    LIMIT 1;
              

    Если всё правильно — вы получите самую популярную услугу за последний год

Общий шаблон для любого варианта


-- 1. Подзапрос: фильтруем нужные данные
SELECT
  внешнее_поле,
  АГРЕГАТНАЯ_ФУНКЦИЯ(внутреннее_поле) AS агрегат
FROM (
  SELECT
    поле1,
    поле2
  FROM таблица
  WHERE условие_фильтрации
) AS имя_подзапроса
-- 2. JOIN с другой таблицей
JOIN другая_таблица ON условие_связи
-- 3. Группировка и агрегация
GROUP BY внешнее_поле
-- 4. Сортировка и выборка
ORDER BY агрегат DESC
LIMIT 1;
        
Создатель сайта не утверждает,
что данная шпаргалка действительно верная
Получить помощь