Предикаты any , all в SQL запросах
-- Использование any , all в запросах , очень похоже на использования предиката exists , но есть некоторые отличия
-- рассмотрим работу данных предикатов на примерах
-- для примера создадим таблицу со следующими полями
-- 1) Название
-- 2) Цвет
-- 3) вес
drop table t1; create table t1(tid number,tname varchar2(20),tprop varchar2(20), tvalue number); -- заполним таблицу данными insert into t1 values(1,'круг','красный', 10); insert into t1 values(2,'круг','зеленый', 30); insert into t1 values(3,'круг','зеленый', 30); insert into t1 values(4,'круг','синий', 20); insert into t1 values(5,'квадрат','красный', 10); insert into t1 values(6,'квадрат','синий', 20); insert into t1 values(7,'квадрат','красный', 20); insert into t1 values(8,'треугольник','красный', 30); insert into t1 values(9,'треугольник','синий', 10);
-- передикат ANY является верным , если из всех значений выведенные подзапросом если любой из их удовлетворяет условию для текущей строки внешнего запроса.
-- давайте рассмотрим на примерах:
select * from t1 where tname = 'круг' and tvalue = any(select tvalue from t1 where tname = 'квадрат' )
TID TNAME TPROP TVALUE
1 круг красный 10
4 круг синий 20
-- таким образом у нас есть два квадрата, вес которых совпадает с весом круга , то есть выполняется условие из подзапроса
-- Предикат ALL является верным, если каждое значение выбранное подзапросом удовлетворяет условию в предикате внешнего запроса.
-- рассмотрим следующий запрос
select * from t1 where tname = 'круг'
and tvalue = all(select tvalue from t1 where tname = 'квадрат')
-- запрос возвращает пустое значение так как все значения tvalue круг не совпадают со значениями подзапроса квадрат, так как нельзя сравнить одну единственную строку основного запроса с каждой строкой подзапроса
select * from t1 where tname = 'круг'
and tvalue = all(select tvalue from t1 where tname = 'квадрат' and tvalue=10)
TID TNAME TPROP TVALUE
1 круг красный 10
-- итак запрос возвращает одну строку
-- то есть в нашем подзапросе возвращается одна строка , в которой значение TVALUE совпадает с одной строкой внешнего запроса
-- следует заметить что предикат all используется в основном в выражениях неравенства , так как выражение когда одно значение равняется нескольким разным другим значениям является по сути бессмысленным
select * from t1 where tname = 'круг'
and tvalue > all(select tvalue from t1 where tname = 'квадрат' )
TID TNAME TPROP TVALUE
2 круг зеленый 30
3 круг зеленый 30
-- инетресна реакция данного предиката на пустой подзапрос
select * from t1 where tname = 'круг'
and tvalue > all(select tvalue from t1 where tname = 'нет такого значения')
TID TNAME TPROP TVALUE
круг красный 10
круг зеленый 30
круг зеленый 30
круг синий 20
-- подзапрос не возвращает строки , однако основной запрос с предикатом вернул все возможные значения - эту особенность необходимо учитывать при построении запросов