Как ANY может стать неоднозначным

Как подразумевалось выше, ANY не полностью однозначен. Если мы соз- даем запрос чтобы выбрать заказчиков которые имеют больший рейтинг чем любой заказчик в Риме, мы можем получить вывод который несколько отли- чался бы от того что мы ожидали ( как показано в Рисунке 13.5 ):     SELECT * FROM Customers WHERE rating > ANY ( SELECT rating FROM Customers WHERE city = Rome );     В английском языке, способ которым мы обычно склонны интерпретиро- вать оценку " больше чем любой ( где city = Rome ) " , должен вам со- общить что это значение оценки должно быть выше чем значение оценки в каждом случае где значение city = Rome. Однако это не так, в случае ANY — исполяьзуемом в SQL . ANY оценивает как верно, если подзапрос на- ходит любое значение которое делает условие верным.  

SQL Execution Log

SELECT *
FROM Customers
WHERE rating > ANY
(SELECT rating
FROM Customers
WHERE city = ‘ Rome ‘);

cnum
cname
city
rating
snum

2002
Giovanni
Rome
200
1003

2003
Liu
San Jose
200
1002

2004
Grass
Berlin
300
1002

2008
Cisneros
San Jose
300
1007

  Рисунок 13.5 Как оператор "больше чем" (>) интерпретируется ANY     Если мы оценим ANY способом исполяьзующим грамматику Английского Язы- ка, то только заказчики с оценкой 300 будут превышать Giovanni, кото- рый находится в Риме и имеет оценку 200. Однако, подзапрос ANY также находит Periera в Риме с оценкой 100. Так как все заказчики с оценкой 200 были выше этой, они будут выбраны, даже если имелся другой заказ- чик из Рима(Giovanni) чья оценка не была выше ( фактически, то что один из выбранных заказчиков также находится в Риме несущественно). Так как подзапрос произвел по крайней мере одно значение которое сде- лает предикат верным в отношении этих строк, строки были выбраны. Что- бы дать другой пример, предположим что мы должны были выбирать все по- рядки сумм приоретений которые были больше чем по крайней мере один из порядков на 6-е Октября:     SELECT * FROM Orders WHERE amt > ANY ( SELECT amt FROM Orders WHERE odate = 10/06/1990 );     Вывод для этого запроса показывается в Рисунке 13.6.     Даже если самая высокая сумма приобретений в таблице (9891.88) — имелась на 6-е Октября, предыдущая строка имеет более высокое значение суммы чем другая строка на 6-е Октября, которая имела значение суммы = 1309.95. Имея реляционный оператор ">=" вместо просто " > ", эта стро- ка будет также выбирана, потому что она равна самой себе. Конечно, вы можете использовать ANY с другой SQL техникой, например с техникой обьединения. Этот запрос будет находить все порядки со зна- чением суммы меньшей чем значение любой суммы для заказчика в San Jo- se (вывод показывается в Рисунке 13.7):     SELECT * FROM Orders WHERE amt < ANY ( SELECT amt FROM Orders A, Customers b WHERE a.cnum = b.cnum AND b.city = " San Jose ‘ );     Даже если нименьший порядок в таблице был для заказчика из San Jose, то был второй наибольший; следовательно почти все строки будут выбра- ны. Простой способ запомнить, что < ANY значение меньшее чем наиболь- шее выбранное значение, а > ANY значение большее чем наименьшее выб- ранное значение.  

SQL Execution Log

SELECT *
FROM Orders
WHERE amt > ANY
(SELECT amt
FROM Orders
WHERE odate = 10/06/1990);

onum
amt
odate
cnum
snum

3002
1900.10
10/03/1990
2007
1004

3005
5160.45
10/03/1990
2003
1002

3009
1713.23
10/04/1990
2002
1003

3008
4723.00
10/05/1990
2006
1001

3011
9891.88
10/06/1990
2006
1001

Рисунок 13. 6: Выбранное значение больше чем любое(ANY) на 6-е Октября  

SQL Execution Log

WHERE amt > ANY
(SELECT amt
FROM Orders a, Customers b
WHERE a.cnum = b.cnum
AND b.city = ‘ San Jose ‘);

onum
amt
odate
cnum
snum

3001
18.69
10/03/1990
2008
1007

3003
767.19
10/03/1990
2001
1001

3002
1900.10
10/03/1990
2007
1004

3006
1098.16
10/03/1990
2008
1007

3009
1713.23
10/04/1990
2002
1003

3007
75.75
10/04/1990
2004
1002

3008
4723.00
10/05/1990
2006
1001

3010
1309.95
10/06/1990
2004
1002

Рисунок 13. 7: Использование ANY с объединением     Фактически, вышеуказанные команды весьма похожи на следующее — (вы- вод показан на Рисунке 13.8) :     SELECT * FROM Orders WHERE amt < ( SELECT MAX amt FROM Orders A, Customers b WHERE a.cnum = b.cnum AND b.city = " San Jose ‘ );

SQL Execution Log

SELECT *
FROM Orders
ORDER BY cnum DESC;

onum
amt
odate
cnum
snum

3002
1900.10
10/03/1990
2007
1004

3005
5160.45
10/03/1990
2003
1002

3009
1713.23
10/04/1990
2002
1003

3008
4723.00
10/05/1990
2006
1001

3011
9891.88
10/06/1990
2006
1001

Рисунок 13.8: Использование агрегатной функции вместо ANY  
 
 
 
 

‹ Использование операторов IN или EXIST вместо оператора ANY
Вверх
Специальный оператор ALL ›

Айтистанция
Добавить комментарий