Joomla 3.1 Templates by FatCow Coupon

Предикаты any , all в SQL запросах

Категория: Блог Опубликовано 24.05.2017

-- Использование 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

-- подзапрос не возвращает строки , однако основной запрос с предикатом вернул все возможные значения - эту особенность необходимо учитывать при построении запросов

Просмотров: 381