таки существует. Она немного более
Но формулировка, эквивалентная исходной и не включающая HAVING, все- таки существует. Она немного более хитрая:
SELECT DISTINCT ( SELECT SUM(SP.QTY) FROM SP) AS TQY FROM SP WHERE (SELECT MIN(SP.QTY) FROM SP) > 50 ;
При выполнении запроса в этой формулировке, если (внешние) разделы FROM и WHERE совместно производят пустую таблицу, то таким будет и результат всего запроса. Причина состоит в том, что единственный элемент, указанный в разделе SELECT является не ссылкой на агрегатную функцию SUM, а скалярным выражением, содержащим такую ссылку. Мощность окончательного результата (т.е. число строк в результирующей таблице) не зависит от вида этого скалярного выражения; можно было бы заменить (SELECT SUM ...) на SP.P#, на SP.QTY или даже на литерал. Более детально, происходит следующее:
- Предположим, что условие раздела WHERE вычисляется в false для каждой строки SP.
- Тогда разделы FROM и WHERE совместно производят пустую таблицу (без строк).
- Подзапрос в разделе SELECT, конечно, возвращает значение 3100. (Более точно, он вырабатывает таблицу с одним столбцом и одной строкой, содержащей численное значение, но SQL извлекает это значение из таблицы. Здесь для нас это обстоятельство не слишком важно, но в SQL вообще оно вызывает проблемы.)
- Итак, обсуждаемая формулировка запроса логически эквивалентна следующей:
SELECT 3100 AS TQY FROM empty ;
(empty именует пустую таблицу.) Очевидно, что результатом такого запроса является таблица с одним столбцом TQY и без строк.
Теперь мы можем сформулировать еще одно правило преобразования: Пусть имеется таблица R{A,B}, и agg1 и agg2 - агрегатные функции, применимые к R.A и R.B соответственно. Тогда выражение
SELECT agg1(R.A) AS C FROM R HAVING agg2(R.B) comp scalar ;
может быть логически преобразовано в эквивалентное выражение
SELECT DISTINCT ( SELECT agg1(R.A) FROM R ) AS C FROM R WHERE ( SELECT agg2(R.B) FROM R ) comp scalar ;
(Здесь comp - некоторый скалярный оператор сравнения, а scalar - некоторое скалярное выражение.)
Будем называть такие преобразования "преобразованиями Типа 3". Читателям рекомендуется самостоятельно разобрать случай, когда формулировка с HAVING включает раздел WHERE.
Содержание Назад Вперед