Представление подзапроса в реляционной алгебре

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

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

3 ответов


вы просто перепишите это как join.

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

  1. возьмите проекцию anotherNumber С anotherStack
  2. переименовать anotherNumber из результата шага 1 Как number
  3. Natural присоединитесь к результату шага 2 на collection
  4. возьмите окончательную проекцию number из результата шага 3

ответ зависит от того, какие операторы алгебре включает. Оператор semi-join был бы наиболее полезен здесь.

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

( collection MATCHING anotherStack ) { number }

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

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

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

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

однако, MATCH не широко поддерживается в реальных продуктах SQL, поэтому полу-соединение обычно пишется с помощью IN (subquery) или EXISTS (subquery) (и я подозреваю, что именно поэтому вы проверили имя "подзапрос" в своем вопросе, т. е. термин semi-join не хорошо известен среди В SQL-практиков).


другим подходом было бы использование оператора intersect, если он доступен.

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

( 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).


по данным этой 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)

to

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, чтобы получить широкий обзор того, как преобразовать суб-запрос в реляционную алгебру.