Программирование >>  Хронологические базы данных 

1 ... 78 79 80 [ 81 ] 82 83 84 ... 348


зультате чего такой запрос, как Получить среднее итоговое количество деталей , нельзя сформулировать без громоздких выражений. Если быть точным, то следующий запрос ***НЕКОРРЕКТЕН***.

SELECT AVG (SUM (SP.QTY) ) ~ Внимание! Это ошибка! FROM SP;

Вместо этого данный запрос следовало бы сформулировать, например, так. SELECT AVG ( X )

FROM ( SELECT SUM ( SP.QTY ) AS X FROM SP

GROUP BY SP.SI ) AS POINTLESS ;

Назначение предложения GROUP BY разъясняется в следующем примере, а использование вложенных подзапросов - несколько ниже. Стоит отметить, что возможность вложения подзапросов в предложение WHERE, как было сделано в этом примере, появилась только в стандарте SQL/92 и еще не используется достаточно широко.

Замечание. Спецификация AS POINTLESS бессмысленна, однако ее наличия требуют синтаксические правила языка SQL (приложение А).

7.7.8. Для каждой поставляемой детали указать номер и общий объем поставки в штуках

SELECT SP.PI, SUM ( SP.QTY ) AS TOTQTY

FROM SP

GROUP BY SP.PI ;

В языке SQL это выражение является аналогом такого выражения реляционной алгебры. SUMMARIZE SP PER SP { Р# } ADD SUM ( QTY ) AS TOTQTY

Oho также является аналогом следующего выражения реляционного исчисления кортежей.

( SPX.PI, SUM ( SPY WHERE SPY.P* = SPX.PI, QTY ) AS TOTQTY )

В частности, стоит отметить, что если в запросе указано предложение GROUP BY, то выражения в предложении SELECT должны быть однозначными для заданной группы. Вот альтернативная, а также более предпочтительная формулировка того же запроса.

SELECT Р.PI, ( SELECT SUM ( SP.QTY ) FROM SP

WHERE SP.PI = P.PI ) AS TOTQTY

FROM P ;

Возможность использования вложенных подзапросов для представления скалярных элементов (например, в предложении SELECT, как здесь) была добавлена в стандарт SQL/92 и является важнейшим усовершенствованием по сравнению с первоначальным вариантом языка SQL. В рассматриваемом примере это предоставляет возможность генерировать результат, который включает строки для деталей, не поставляемых со-



всем, а предыдущая формулировка (использующая предложение GROUP BY) этого не позволяла. (Однако значение TOTQTY для таких деталей будет, к сожалению, представлено как NULL-значение, а не нуль.)

7.7.9. Указать номера всех типов деталей, поставляемых более чем одним поставщиком

SELECT SP.PI

FROM SP

GROUP BY SP.PI

HAVING COUNT ( SP.Sl ) > 1 ;

Предложение HAVING в отношении групп является тем же, что и предложение WHERE для обычных строк. Другими словами, предложение HAVING используется для исключения групп аналогично тому, как предложение WHERE используется для исключения отдельных строк. Выражение в предложении HAVING должно быть однозначным для заданной группы.

7.7.10. Определить имена поставщиков детали с номером Р2

SELECT DISTINCT S.SNAME FROM S WHERE S.SI IN

( SELECT SP.Sl FROM SP

WHERE SP.PI = P2 ) ; Пояснения. В этом примере в предложении WHERE используется так называемый подзапрос. Проще говоря, подзапрос- это выражение из предложений SELECT-FROM-WHERE-GROUP BY-HAVING, которое вложено в другое такое же выражение. Подзапрос чаще всего используется для представления множества значений, поиск которых осуществляется с помощью предложения IN условие, что и представлено в данном в примере. Система вычисляет запрос в целом, предварительно вычислив указанный подзапрос (по крайней мере, концептуально). Подзапрос в данном примере возвращает множество номеров поставщиков детали с номером Р2: {S1, S2, S3, S4}. Таким образом, первоначальное выражение эквивалентно следующему, более простому,

SELECT DISTINCT S.SNAME FROM S

WHERE S.SI IN ( SI, S2, S3, S4 ) ;

Стоит отметить, что первоначальную задачу - Получить имена поставщиков детали с номером Р2 - можно равносильно выразить с помощью операции соединения, например, так.

SELECT DISTINCT S.SNAME FROM S, SP WHERE S.SI = SP.Sl AND SP.PI = P2 ;



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

SELECT DISTINCT S.SNAME FROM S WHERE S.S# IN

( SELECT SP.SI FROM SP WHERE SP.PI = IN ( SELECT P.P# FROM P

WHERE P.COLOR = Red ) ) ; Подзапросы могут иметь произвольную глубину вложения.

Упражнение. Приведите эквивалентную формулировку этого запроса с использованием операции соединения.

7.7.12. Указать номера поставщиков, статус которых меньше текущего максимального статуса

в таблице S

SELECT S.SI FROM S

WHERE S.STATUS <

( SELECT MAX ( S.STATUS ) FROM S ) ;

В этом примере используются две отдельные неявные переменные кортежей, обозначенные одним и тем же именем S и изменяющиеся на таблице S.

7.7.13. Указать имена поставщиков детали с номером Р2

Замечание. Этот пример повторяет пример 7.7.10. Ниже приводится другое решение для того, чтобы представить еще одно средство языка SQL.

SELECT DISTINCT S.SNAME FROM S WHERE EXISTS

( SELECT * FROM SP

WHERE SP.SI = S.S# AND SP.PI = P2 ) ;

Яоясне ме. SQL-выражение EXISTS (SELECT ... FROM ...) будет иметь значение мстм-на тогда и только тогда, когда результат вычисления выражения SELECT ... FROM ... будет непустым. Другими словами, в языке SQL функция EXISTS соответствует квантору существования реляционного исчисления [18.6].



1 ... 78 79 80 [ 81 ] 82 83 84 ... 348

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика