如何在关系代数中表示子查询?我是否将新选择置于先前的选择条件下?
SELECT number
FROM collection
WHERE number = (SELECT anotherNumber FROM anotherStack);
如何在关系代数中表示子查询?我是否将新选择置于先前的选择条件下?
SELECT number
FROM collection
WHERE number = (SELECT anotherNumber FROM anotherStack);
您只需将其重写为join
.
我不确定我从关系代数中学到的语法在语言中的使用范围有多广。
anotherNumber
对from进行投影anotherStack
anotherNumber
为number
collection
number
从步骤 3 的结果中进行最终投影答案取决于您的代数包含哪些运算符。半连接运算符在这里最有用。
如果在两个关系中都命名了公共属性,number
那么它将是一个半连接,然后是 的投影number
。MATCHING
假设按照教程 D命名为 sem-join 运算符:
( 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
);
但是,在现实生活中的 SQL 产品中并未得到广泛支持,因此为什么通常使用orMATCH
编写半联接(我怀疑这就是为什么您在问题中对“子查询”进行名称检查的原因,即术语半联接在SQL 从业者)。IN (subquery)
EXISTS (subquery)
另一种方法是使用相交运算符(如果可用)。
类似(伪代码):
( 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)
至
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 以大致了解如何将子查询转换为关系代数。