|
Программирование >> Sql: полное руководство
Иногда проверка any может оказаться трудной для понимания, поскольку включает в себя не одно сравнение, а несколько. Если прочитать условие сравнения немного по-другому, это поможет понять его смысл. Например, проверку WHERE X < ANY (SELECT Y .. .) следует читать не как где X меньше, чем любой выбранный Y... а так: где для некоторого Y X меньше, чем Y... Тогда преа;ыдущий запрос можно перефразировать следующим образом: Вьшести Список служашюс, у которых для некоторого заказа, принятого ими, десять процентов от планового объема продаж служащего меньше, чем стоимость заказа . Если подчищенный запрос в проверке any не создает ни одной строки или если столбец результатов содержит значения null, то в различных СУБД проверка any может выпол1 яться по-разному. В стандарте ANSI/ISO для языка SQL содержатся подробные пр авила, определяющие результаты проверки any, когда проверяемое значение сравнивается со столбцом результатов подчиненного запроса. Если подаиненный запрос возвращает результат в виде пустого столбца, то проверка a.ny возвращает значение false (в результате вьшолнения подчиненного запроса не получезд ни одного значения, для которохо выполнялось бы условие срвавнения). Если опер-ация сравнения имеет значение true хотя бы для одного значения в столбце, то проверка any возвращает значение true (имеется некоторое значение, полученно е подчиненным запросом, для которого условие сравнения вьшолняется). Если опер.ация сравнения имеет значение false для всех значений в столбце, то яровервса any возвращает значение false (можно утверждать, что ни для одного значения, возвращенного подчиненным запросом, условие сравнения не выполняетгся). Если опероация сравнения не имеет значение true ни для одного значения в столбце, ню в нем имеется одно или несколько значений null, то проверка any возвращае-т результат null. (В этой ситуации невозможно с определенностью утверждатж существует ли полученное подчиненным запросом значение, для которого выполняется условие сравнения; может быть, существует, а может и нет - все зависит от настоящих значений неизвестных данных.) На практизке проверка ajy иногда может приводить к ошибкам, которые трудно выявить, ocoSeHHO когда применяется оператор сравнения не равно (<>). Ваг пример, иллю..стрирующий данную проблему: Вывести имена и данные о возрасте всех служащих, которые не руководят офисами .. Заманчиво было бы выразить запрос таким образом: SELECT NAME, AGE FROM salesi54eps WHERE EMPL k4um <> ANY (SELECT MGR FROM OFFICES) Подчиненный запрос SELECT MGR FROM OFFICES в качестве результатов возвращает идентификаторы служащих, являющихся руководителями офисов, поэтому кажется, что запрос имеет следующий смысл: Найти всех служащих, не являющихся руководителями офисов . Но это не так] На самом деле приведенный запрос означает: Найти всех служащих, которые для некоторого офиса не являются руководителями этого офиса . Конечно, для любого служащего можно найти некоторый офис, руководителем которого данный служащий не является. В таблицу результатов запроса войдут все служащие, поэтому запрос не дает ответа на поставленный вопрос! А правильным яв 1яется следующий запрос: SELECT ЫАМЕ, AGE FROM SALESREPS WHERE NOT (EMPL NOM = ANY (SELECT MGR FROM OFFICES)) NAME AGE Mary Jones 31 Sue Smith 4 8 Dan Roberts 45 Tom Snyder 41 Paul Cruz 2 9 Nancy Angelli 4 9 Запрос с предикатом any всегда можно преобразовать в запрос с предикатом exists, перенося операцию сравнения внутрь условия отбора подчиненного запроса. Обьино так и следует поступать, поскольку в этом случае исключаются ощибки, подобные описанной вьпие. Вот альтернативная форма запроса с проверкой exists: SELECT NAME, AGE FROM SALESREPS WHERE NOT EXISTS (SELECT * / FROM OFFICES NAME AGE WHERE EMPL NOM = MGR) Mary Jones 31 Sue Smith 4 8 Dan Roberts 4 5 Tom Snyder 41 Paul Cruz 29 Nancy Angelli 4 9 Предикат ALL * В проверке all, как и в проверке any, используется один из щести операторов (~> о, <, <=, >, >=) для сравнения проверяемого значения со столбцом данных. отобранных подчиненным запросом. Проверяемое значение поочередно сравнивается с каждым элементом, содержащимся в столбце. Если все сравнения дают результат true, то проверка all возвращает значение true. Вот пример запроса с предикатом all: Вывести список тех офисов с их плановыми объемами продаж, для всех служащих которых фактический объем продаж превышает 50 процентов от плана офиса. SELECT CITY, TARGET FROM OFFICES WHERE (.50 * TARGET) < ALL (SELECT SALES FROM SALESREPS WHERE REP OFFICE = OFFICE) CITY TARGET Denver $300,000.00 New York $575,000.00 Atlanta $350,000.00 Главный запрос поочередно проверяет каждую строку таблицы offices. Подчиненный запрос находит всех служащих, работающих в текущем офисе, и возвращает столбец с фактическими объемами продаж для каждого служащего. Предложение where главного запроса вычисляет 50 процентов от плана продаж офиса и сравнивает это значение со всеми объемами продаж, получаемыми в результате выполнения подчиненного запроса. Если все объемы продаж превышают проверяемое значение, то проверка < all возвращает значение true и данный офис включается в таблицу результатов запроса. Если нет, то офис не попадает в таблицу результатов. Проверка all, подобно проверке any, может оказаться трудной для понимания, поскольку включает в себя не одно сравнение, а несколько. Опять-таки, если читать условие сравнения немного иначе, то это помогает понять его смысл. Например, проверку WHERE X < ALL (SELECT Y...) следует читать не как где X меньше, чем все выбранные Y... а так- где для всех У X меньше, чем Y... Тогда предыдущий запрос можно представить в таком виде: Вывести список офисов, где для всех служащих 50 процентов плана офиса меньше, чем фактический объем продаж каждого служащего . Если подчиненный запрос в проверке all не возвращает ни одной строки или если столшбец результатов запроса содержит значения null, то в различных СУБД проверка all может выполняться по-разному. В стандарте ANSI/ISO для языка SQL содержатся подробные правила, определяющие результаты проверки all, когда проверяемое значение сравнивается со столбцом результатов подчиненного запроса- Если подчиненный запрос возвращает результат в виде пустого столбца, то проверка all возвращает значение true. Считается, что условие сравнения выполняется, даже если результаты подчиненного запроса отсутствуют.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |