Помнишь оператор IN
из темы "Отсечение строк и сортировка"? Вот пример
SELECT *
FROM store
WHERE store_id IN (100, 300, 500)
В результат попадут магазины с идентификаторами 100, 300 и 500. Если store_id
для строки равен одному из значений, перечисленных в IN
, то условие принимает значение TRUE
и строка попадает в результат.
Список значений внутри IN
можно заменить подзапросом. Подзапрос внутри IN
используют, когда список значений заранее неизвестен и определяется хранимыми в таблицах данными.
Например, выведем информацию о товарах, которые доступны в магазинах дешевле 15000:
SELECT *
FROM product p
WHERE p.product_id IN (SELECT pp.product_id
FROM product_price pp
WHERE pp.price < 15000)
# | product_id | category_id | name | description |
---|---|---|---|---|
1 | 1 | 3 | Пылесос S6 | 1400 вт |
2 | 7 | 10 | Deepbox | Нейлон |
Подзапрос
SELECT pp.product_id
FROM product_price pp
WHERE pp.price < 15000
вернет следующие строки
# | product_id |
---|---|
1 | 1 |
2 | 1 |
3 | 1 |
4 | 7 |
Список значений внутри IN
будет заменен на (1, 1, 1, 7).
Этот запрос можно переписать, используя JOIN
+ DISTINCT
:
SELECT DISTINCT
p.*
FROM product p
JOIN product_price pp
ON pp.product_id = p.product_id
WHERE pp.price < 15000
Проверку IN
можно выполнять по нескольким столбцам. Для этого их необходимо взять в скобки, а из подзапроса возвращать несколько столбцов. Выведем информацию о продуктах заказа, которые проданы по цене из каталога:
SELECT pi.*
FROM purchase_item pi
JOIN purchase p
ON p.purchase_id = pi.purchase_id
WHERE (pi.product_id, p.store_id, pi.price) IN
(SELECT pp.product_id, pp.store_id, pp.price
FROM product_price pp)