关系代数相当于SQL“NOT IN”

时间:2012-09-22 07:27:50

标签: sql relational-algebra

是否存在与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

3 个答案:

答案 0 :(得分:6)

在关系代数中,您可以使用carthesian产品执行此操作。类似的东西:

R - ρ a1,a2 (π a11,a21 (σ A11 = A22 (ρ a11,a21 (R)xρ a12,a22 (R))))

  • 重命名R,f.e。的列。从a1到a11(左手)和a12(右手)
  • 使用重命名列
  • 的R的叉积
  • 选择a11等于a22
  • 的行
  • 预测a12和a22并保持a11和a21
  • 重命名为a1和a2

它为您提供匹配的行。从R中减去它以找到不匹配的行。

答案 1 :(得分:2)

开场问题让我们误入歧途。它应该是:

是否存在与SQL表达式R WHERE ... [NOT] IN S相当的关系代数?

(也就是说,答案是两个关系之间的某些操作,某种过滤器。)

答案是肯定的,它是(自然的)JOIN又名领结算子

要了解原因,让我们首先整理给出的SQL解决方案。如图所示,它正在寻找属性A1 NOT IN与单个属性A2的关系。这真的是属性名称的不匹配。 SQL还允许在where条件中使用NOT。这个SQL使逻辑结构更清晰:

SELECT * FROM R
WHERE NOT (A1 IN (SELECT A2 AS A1 FROM R) )

现在我们可以看到投影和重命名。 (根据第一个答案,我们可以按照设置MINUS实现周围的NOT。)所以等效的RA是:

R - (R ⋈ ρ <子> A1/A2 <子> A2 (R)))

有兴趣的话,教程D是:

R MINUS (R JOIN (R {A2} RENAME A2 AS A1))

在提出这个问题的方式中,SQL思维会有一些遗留问题。 SQL的WHERE强制您进入行级“模式”。这与Codd的规则7相反,后者需要一次性设定运营商。

一般情况下,SQL的WHERE和RA的σ及其行级过滤器可以更简洁地实现为(自然)JOIN,具有一次性设置逻辑。 (例如,这就是Date&amp; Darwen在 A 代数中所做的事情。)

答案 2 :(得分:0)

直接回答一个更普遍的问题:

SELECT
    *
FROM
    R
WHERE
    R.A1 NOT IN
        (
        SELECT
            A2
        FROM
            S
        );

答案是:

R-R "bowtie" [R.A1=S.A2] ("pi" [A2] S )