【发布时间】:2010-10-03 17:36:57
【问题描述】:
如何在关系代数中表示子查询?我是否将新的选择置于先前的选择条件下?
SELECT number
FROM collection
WHERE number = (SELECT anotherNumber FROM anotherStack);
【问题讨论】:
如何在关系代数中表示子查询?我是否将新的选择置于先前的选择条件下?
SELECT number
FROM collection
WHERE number = (SELECT anotherNumber FROM anotherStack);
【问题讨论】:
您只需将其重写为join。
我不确定我从关系代数中学到的语法在语言中的使用范围有多广。
anotherStack 投影anotherNumber anotherNumber 重命名为 number
collection
number 进行最终投影【讨论】:
答案取决于您的代数包含哪些运算符。半连接运算符在这里最有用。
如果公共属性在两个关系中都命名为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 不支持)。
【讨论】:
根据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 以大致了解如何将子查询转换为关系代数。
【讨论】: