【问题标题】:Represent a subquery in relational algebra表示关系代数中的子查询
【发布时间】:2010-10-03 17:36:57
【问题描述】:

如何在关系代数中表示子查询?我是否将新的选择置于先前的选择条件下?

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

【问题讨论】:

    标签: sql relational-algebra


    【解决方案1】:

    您只需将其重写为join

    我不确定我从关系代数中学到的语法在语言中的使用范围有多广。

    1. anotherStack 投影anotherNumber
    2. 将步骤 1 的结果中的 anotherNumber 重命名为 number
    3. 自然将第 2 步的结果加入到collection
    4. 从第 3 步的结果中对number 进行最终投影

    【讨论】:

    • 一个可以将其重写为一个连接:)
    【解决方案2】:

    答案取决于您的代数包含哪些运算符。半连接运算符在这里最有用。

    如果公共属性在两个关系中都命名为number,那么它将是一个半连接,然后是number 的投影。假设有一个名为MATCHING 的sem-join 运算符,根据Tutorial 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 不支持)。

    【讨论】:

    • 您在选择词语时应该更精确一些。如果 MATCH 可以在 WHERE 子句中使用(以您描述的方式),那么该运算符必须返回一个布尔值,然后 MATCH 不可能是“一个 SEMIJOIN 运算符”,正如您所声称的那样。 SEMIJOIN 运算符返回一个关系。
    【解决方案3】:

    根据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...是子查询关系。

    由于堆栈溢出的语法非常糟糕,请转到that pdf 以大致了解如何将子查询转换为关系代数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      • 2016-08-12
      相关资源
      最近更新 更多