Реляционная Алгебра эквивалент SQL " не в"
Существует ли реляционная алгебра, эквивалентная выражению SQL NOT IN
?
Например, если у меня есть отношение:
A1 | A2
----------
x | y
a | b
y | x
Я хочу удалить все Кортежи в отношении, для которого A1 находится в A2. В SQL я мог бы запросить:
SELECT
*
FROM
R
WHERE
R.A1 NOT IN
(
SELECT
A2
FROM
R
)
/
Что действительно ставит меня в тупик, так это как сделать подзапрос внутри оператора выбора реляционной алгебры, возможно ли это?:
Σ некоторый подзапрос здесь R
2 ответа:
В реляционной алгебре это можно сделать с помощью картезианского произведения. Что-то вроде:
R-ρa1, a2 (πa11, a21 (σ A11 = A22 (ρ a11, a21(R) x ρa12, a22(R)))
- переименуйте столбцы R, т. е. из a1 в a11 (левая рука) и a12 (правая рука)
- возьмем поперечное произведение R с переименованными столбцами
- выберите строки, где a11 равно a22
- спроецируйте a12 и a22 и сохраните a11 и a21
- переименовать к a1 и a2
Это дает вам строки, которые были сопоставлены. Вычтите это из R, чтобы найти строки, которые не совпадают.
Первый вопрос посылает нас вниз по неправильному мышлению. Это должно быть:
Существует ли реляционная алгебра, эквивалентная выражению SQLR WHERE ... [NOT] IN S
?(то есть ответ-это некоторая операция между двумя отношениями, не какой-то фильтр.)
Ответ-Да, это (естественно)
JOIN
ака оператор бабочки⋈
.Чтобы понять, почему, давайте сначала приведем в порядок данное решение SQL. Как показано, он ищет атрибут
A1 NOT IN
отношение с одним атрибутA2
. Это действительно неправильное совпадение в именах атрибутов. SQL также допускаетNOT
внутри условия where. Этот SQL делает логическую структуру более ясной:Теперь мы можем видеть проекцию и переименование. (ОкружающееSELECT * FROM R WHERE NOT (A1 IN (SELECT A2 AS A1 FROM R) )
NOT
мы можем реализовать как множество минус, согласно первому ответу.) Таким образом, эквивалентное РА:
R - (R ⋈ ρ
A1⁄A2(π
А2(R)))
Для интереса, учебник D:
R MINUS (R JOIN (R {A2} RENAME A2 AS A1))
В том, как поставлен вопрос, есть похмелье от SQL-мышления. SQL
WHERE
заставляет вас перейти в "режим" на уровне строк. Это правило 7 contra Codd, требующее операторов set-at-time.В общем случае SQL
WHERE
и RAσ
с их фильтрами уровня строк могут быть более лаконично реализованы как (естественные)JOIN
с логикой set-at-time. (Например, это то, что Date & Darwen делают в своих а алгебра.)