Представлять подзапрос в реляционной алгебре - PullRequest
6 голосов
/ 03 октября 2010

Как мне представить подзапрос в алгебре отношений? Поместить ли новый выбор под предыдущее условие выбора?

SELECT number
FROM collection
WHERE number = (SELECT anotherNumber FROM anotherStack);

Ответы [ 3 ]

8 голосов
/ 05 октября 2010

Вы просто переписали бы это как join.

Я не уверен, насколько широко использовался синтаксис, который я выучил для реляционной алгебры.

  1. Возьмите проекцию anotherNumber из anotherStack
  2. Переименовать anotherNumber из результата шага 1 в number
  3. Natural Соедините результат шага 2 на collection
  4. Возьмите окончательный прогноз number от результата шага 3
1 голос
/ 14 октября 2011

Ответ зависит от того, к каким операторам относится ваша алгебра.Оператор полусоединения был бы наиболее полезным здесь.

Если общий атрибут был назван number в обоих отношениях, то это было бы полусоединение с последующей проекцией number.Предполагая, что оператор соединения sem с именем MATCHING, согласно Учебное пособие D :

( collection MATCHING anotherStack ) { number }

После публикации, атрибут должен быть сначала переименован:

( collection MATCHING ( anotherStack RENAME { anotherNumber AS number } ) { number }

Если стандартный SQL (SQL-92) JOIN можно считать, грубо говоря, реляционным оператором, то верно, что SQL не имеет полусоединения.Однако он имеет несколько предикатов сравнения, которые можно использовать для написания оператора полусоединения, например MATCH:

SELECT number
  FROM collection
 WHERE MATCH (
              SELECT * 
                FROM collection
               WHERE collection.number = anotherNumber.anotherStack
             );

Однако MATCH широко не поддерживается в реальных продуктах SQL, поэтому, почемуПолу-соединение обычно пишется с использованием IN (subquery) или EXISTS (subquery) (и я подозреваю, что именно поэтому в вашем вопросе вы проверили именованный «подзапрос», т. е. термин «полу-соединение» не очень известен среди практиков SQL).


Другой подход заключается в использовании оператора пересечения, если он доступен.

Что-то вроде (псевдокод):

( collection project number ) 
intersect 
( ( anotherStack rename anotherNumber as number ) project number )

В SQL:

SELECT number
  FROM collection
INTERSECT
SELECT anotherNumber
  FROM anotherStack;

Это довольно хорошо поддерживается в реальной жизни (SQL Server, Oracle, PostgreSQL и т. Д.но особенно не MySQL).

0 голосов
/ 07 июля 2018

Согласно this pdf вы можете легко преобразовать подзапрос в реляционное алгебраическое выражение.

Во-первых, вы должны преобразовать весь запрос из формы

SELECT Select-list FROM R1 T1, R2 T2, ...
WHERE
some-column = (
    SELECT some-column-from-sub-query from r1 t1, r2 t2, ...
    WHERE extra-where-clause-if-needed)

до

SELECT Select-list FROM R1 T1, R2 T2, ...
WHERE
EXISTS (
    SELECT some-column-from-sub-query from r1 t1, r2 t2, ...
    WHERE extra-where-clause-if-needed and some-column = some-column-from-sub-query)

Затем вы должны сначала преобразовать подзапрос в реляционную алгебру. Чтобы сделать это для подзапроса, указанного выше:

PI[some-column-from-sub-query](
    SIGMA[extra-where-clause-if-needed 
        ^ some-column = some-column-from-sub-query
        ](RO[T1](R1) x RO[T2](R2) x ... x RO[t1](r1) x RO[t2](r2) x ...)
)

Здесь R1, R2... - это контекстные отношения, а r1, r2... - это отношения подзапроса.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...