Продвинутые SQL-запросы

Теория: Подзапрос

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

Подзапрос SQL

Применение подзапросов

Подзапросы могут применяться практически везде, в любых операторах, в том числе в операторах DDL, DML.

Рассмотрим таблицу products:

products

idproduct_nameprice
10928473Стиральная машина Electrolux28499.99
20483739Беспроводные наушники JBL с микрофоном4999.0
73648393Игровая мышь Acer1099.0
.........

Пример подзапроса, который выводит все продукты, цена которых выше средней по всем продуктам:

SELECT *
FROM products
WHERE price > (SELECT AVG(price) FROM products);

В результате мы получим такую таблицу:

products

idproduct_nameprice
10928473Стиральная машина Electrolux28499.99
66379812Ноутбук Dell90299.0
33801167Ноутбук Acer53849.0
99842651Электровелосипед HIPER19999.0

Таблица на DB Fiddle

Пример подзапроса, который выводит все продукты, которые есть в таблице с чеками:

SELECT *
FROM products
WHERE
    id IN
    (SELECT product_id FROM sales);

Результат будет следующим:

products

idproduct_nameprice
10928473Стиральная машина Electrolux28499.99
20483739Беспроводные наушники JBL с микрофоном4999.0
73648393Игровая мышь Acer1099.0
17728904Компьютерная мышь Logitech650.0

Таблица на DB Fiddle

ALL/ANY (MySQL)

ALLANY
x > ALL (1, 2) эквивалентно x > 2x > ANY (1, 2) эквивалентно x > 1
x < ALL (1, 2) эквивалентно x < 1x < ANY (1, 2) эквивалентно x < 2
x = ALL (1, 2) эквивалентно (x = 1) AND (x = 2)x = ANY (1, 2) эквивалентно x IN (1, 2)
x <> ALL (1, 2) эквивалентно x NOT IN (1, 2)x <> ANY (1, 2) эквивалентно (x <> 1) OR (x <> 2)

Подзапрос как новая колонка

Подзапросы в SQL могут быть использованы для создания новых колонок в результирующем наборе данных.

Новая колонка, созданная с помощью подзапроса, может содержать вычисленные значения, агрегатные функции или другие данные, основанные на значениях других столбцов в таблице

SELECT
    *,
    (
        SELECT product_name
        FROM products
        WHERE id = sales.product_id
    ) AS product
FROM sales;

Результат будет таким:

products

product_idsale_datequantitytotal_priceproduct
109284732023-03-08T00:00
.000Z
128500Стиральная машина Electrolux
...............
109284732023-06-13T00:00
.000Z
5142500Стиральная машина Electrolux

Таблица на DB Fiddle

Подзапросы в UPDATE

Одно из основных применений подзапросов в операции UPDATE - это обновление значений столбца на основе вычисленных или фильтрованных данных из других таблиц или столбцов.

UPDATE sales
SET
    price = (
        SELECT products.price
        FROM products
        WHERE products.id = sales.product_id
    ) + 3000
WHERE id = 1;

Таблица на DB Fiddle

Подзапросы в INSERT

Подзапросы в операции INSERT используются для вставки данных, полученных из других таблиц или вычисленных с помощью подзапросов.

INSERT INTO sales (product_id, sale_date, quantity, total_price)
VALUES
(
    (SELECT id FROM products WHERE product_name = 'Фен Vitek'),
    '2018-05-23',
    2,
    (SELECT price FROM products WHERE product_name = 'Фен Vitek')
);

Таблица на DB Fiddle

Подзапросы в DELETE

Подзапросы в операции DELETE позволяют удалить данные из таблицы на основе результатов других запросов или данных из других таблиц.

DELETE FROM sales
WHERE product_id = (
    SELECT id
    FROM products
    WHERE product_name = 'Игровая мышь Acer'
);

Таблица на DB Fiddle

Коррелированный подзапрос

Коррелированный подзапрос - это подзапрос, который зависит от внешнего запроса и использует значения из внешнего запроса в своем выражении или фильтре.

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

SELECT *
FROM product_price AS pp
WHERE
    pp.price = (
        SELECT min(ppm.price)
        FROM product_price AS ppm
        WHERE ppm.product_id = pp.product_id
    )
ORDER BY pp.product_id, pp.price, pp.store_id

products

product_idstore_idprice
10928473128499.99
177289041650.00
2048373914999.00
7364839311099.00

Таблица на DB Fiddle

Рекомендуемые программы