Database Programming & Design
859c2d4a

Переменные с областью значений (range variables)


Замечание С.Кузнецова по поводу русскоязычной терминологии: На английском языке словосочетание "range variable" лаконично и правильно отражает суть понятия. К сожалению, до сих пор мне не удалось найти столь же лаконичный русский эквивалент, хотя было много попыток. Когда-то я пытался ввести в оборот термин "ранжированная переменная", но мне справедливо указали на отсутствие явного смысла в этом словосочетании. Если кто-нибудь знает, как лучше обозначать рассматривамое понятие на русском языке, дайте мне знать, пожалуйста.

Рассмотрим следующий запрос:

Q9: Выдать все пары номеров поставщиков, располагающихся в одном и том же городе

На языке SQL возможна следующая формулировка этого запроса:

SELECT FIRST.S# AS SX, SECOND.S# AS SY FROM S AS FIRST, S AS SECOND WHERE FIRST.CITY = SECOND.CITY

FIRST и SECOND являются примерами того, что в SQL называется корреляционными именами. Однако заметим, что SQL ничего не говорит о том, что именно именуют эти имена! В отличие от этого, в реляционном исчислении такие имена определяются для ссылок на переменные с областью значения, и далее будет использоваться этот термин.

Переменная с областью значений - это переменная, определенная на некоторой конкретной таблице; значениями переменной являются строки этой таблицы. Если областью значений переменной r является таблица R, то в каждый момент времени значением выражения "r" является некоторая строка R. В SQL переменные с областью значений вводятся посредством спецификации AS в разделе FROM (не нужно путать эту спецификацию со спецификацией AS в разделе SELECT, которая позволяет назначить имя столбцу результирующей таблицы).

Покажем, что, подобно разделам GROUP BY и HAVING, переменные с областью значений являются логически избыточными в языке SQL (несмотря на то, что они активно использовались в предыдущих примерах). Для иллюстрации сначала приведем формулировку запроса Q9 без использования переменных с областью значений:

SELECT SX, SY FROM ( SELECT S.S# AS SX, S.CITY FROM S) AS POINTLESS1 ) NATURAL JOIN ( SELECT S.S# AS SY, S.CITY FROM S) AS POINTLESS2 )


Замечание С.Кузнецова: Напомним, что здесь используется SQL-92, в котором допустимы и такие "алгебраические" формулировки.

Как видно, в этой формулировке на самом деле определяются две переменных с областью значений - POINTLESS1 и POINTLESS2, но логически они не требуются, поскольку отсутствуют ссылки на эти переменные. Они введены исключительно для того, чтобы удовлетворить синтаксические требования языка SQL.

В качестве второго примера используем запрос Q1 из первой части заметки:

Q1: Для каждой поставляемой детали выдать номер детали, максимальный и минимальный объем поставки этой детали.

Вот формулировка этого запроса без использования переменных с областью значений (равно как и разделов GROUP BY и HAVING):

SELECT DISTINCT PZ AS P#, ( SELECT MAX(SP.QTY) FROM SP WHERE SP.P# = PZ ) AS MXQ, ( SELECT MIN(SP.QTY) FROM SP WHERE SP.P# = PZ ) AS MNQ FROM ( SELECT SP.P# AS PZ FROM SP ) AS POINTLESS ;

Как и в предыдущем примере, в этой формулировке вводится переменная с областью значений POINTLESS, но логически она не требуется, поскольку на эту переменную отсутствуют ссылки.

В завершение раздела заметим, что переменные с областью значений должны быть необязательными в SQL, поскольку


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



Содержание раздела