Коррелированным подзапросом называется подзапрос, который ссылается на значения столбцов внешнего запроса.
Коррелированный подзапрос выполняется для каждой строки основного запроса. В момент выполнения подзапроса значения столбцов внешнего запроса являются константами.
Пример. Для каждого товара найдем магазины, в которых его можно купить по минимальной цене.
Весь каталог товаров:
SELECT *
FROM product_price pp
ORDER BY pp.product_id, pp.price, pp.store_id
# | product_id | store_id | price |
---|---|---|---|
1 | 1 | 300 | 10500.00 |
2 | 1 | 800 | 12000.00 |
3 | 1 | 301 | 12500.00 |
4 | 2 | 500 | 26100.00 |
5 | 2 | 600 | 27500.00 |
... | ... | ... | ... |
13 | 5 | 201 | 23500.00 |
14 | 5 | 500 | 23500.00 |
15 | 5 | 800 | 24600.00 |
... | ... | ... | ... |
Оставим записи с минимальной ценой:
SELECT *
FROM product_price pp
WHERE pp.price = (SELECT min(ppm.price)
FROM product_price ppm
WHERE ppm.product_id = pp.product_id)
ORDER BY pp.product_id, pp.price, pp.store_id
# | product_id | store_id | price |
---|---|---|---|
1 | 1 | 300 | 10500.00 |
2 | 2 | 500 | 26100.00 |
3 | 3 | 500 | 22000.00 |
4 | 4 | 400 | 20000.00 |
5 | 5 | 201 | 23500.00 |
6 | 5 | 500 | 23500.00 |
... | ... | ... | ... |
Разберем, как получился такой результат. Для каждой строки, полученной в результате соединения таблицы из предложения FROM
# | product_id | store_id | price |
---|---|---|---|
1 | 1 | 300 | 10500.00 |
2 | 1 | 800 | 12000.00 |
3 | 1 | 301 | 12500.00 |
4 | 2 | 500 | 26100.00 |
5 | 2 | 600 | 27500.00 |
... | ... | ... | ... |
13 | 5 | 201 | 23500.00 |
14 | 5 | 500 | 23500.00 |
15 | 5 | 800 | 24600.00 |
... | ... | ... | ... |
выполняется подзапрос
SELECT min(ppm.price)
FROM product_price ppm
WHERE ppm.product_id = pp.product_id
в котором pp.product_id
заменяется значеним product_id
из обрабатываемой строки.
Для строки
# | product_id | store_id | price |
---|---|---|---|
1 | 1 | 300 | 10500.00 |
запрос
SELECT min(ppm.price)
FROM product_price ppm
WHERE ppm.product_id = 1
вернет значение 10500.00, которое совпадает с pp.price
. Строка попадает в результат выполнения запроса.
Для строки
# | product_id | store_id | price |
---|---|---|---|
2 | 1 | 800 | 12000.00 |
SELECT min(ppm.price)
FROM product_price ppm
WHERE ppm.product_id = 1
вернет значение 10500.00. Во второй строке pp.price
= 12000.00. Строка исключается из результата выполнения запроса.
Третья строка исключается аналогично второй.
Для четвертой строки будет выполняться подзапрос
SELECT min(ppm.price)
FROM product_price ppm
WHERE ppm.product_id = 2
И так далее..