Продвижение сайта по поисковым запросам, контекстная реклама, качественный копирайтинг и рерайтинг, создание сайта под ключ, QA процедуры и аудит в ИТ, бизнес анализ в Киеве, Украина.

Поиск

Админ

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


Как 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.

===============  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-е Октября.

Даже если самая высокая сумма приобретений в таблице (9891.88) — имелась на 6-е Октября, предыдущая строка имеет более высокое значение суммы, чем другая строка на 6-е Октября, которая имела значение суммы = 1309.95. Если мы введем реляционный оператор ">=" вместо просто ">", эта строка будет также выбрана, потому что она равна самой себе.

Конечно, вы можете использовать ANY с другой SQL техникой, например с техникой объединения. Этот запрос будет находить все Заказы со значением суммы меньшей, чем значение любой суммы для заказчика в San Jose. (вывод показывается в Рисунке 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 ==============
| 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.10  10/03/1990   2001     1001  |
|   3002     1900.10  10/03/1990   2007     1004  |
|   3006     1098.10  10/03/1990   2008     1007  |
|   3009     1713.23  10/04/1990   2002     1003  |
|   3007       75.10  10/04/1990   2004     1002  |
|   3008     4723.00  10/05/1990   2006     1001  |
|   3010     1309.88  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 ==============
| WHERE amt <                                     |
| (SELECT MAX (amt)                               |
| FROM Orders a, Customers b                      |
| WHERE a.cnum = b.cnum                           |
| AND b.city = 'San Jose');                       |
| =============================================== |
|   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.

Популярность: 4%




Оставить комментарий или два


Навигация

Блог / Главная / Разработка / Как ANY может стать неоднозначным

Инфо

Запись опубликовал admin 27 апреля 2010 года и разместил в рубрике Разработка.   Запись имеет метки:   К статье пока нет комментариев. Вы можете быть первым.  

Случайные записи

Справочник по командам и синтаксису sql Внешние ключи, которые ссылаются обратно к их подчиненным таблицам sql Объявление переменных sql Управление изменениями проекта.