是否可以解相关所有相关的SQL子查询?

时间:2018-02-08 18:21:49

标签: sql theory relational-algebra

(注意:不是this question的副本,因为该问题有一个特定的查询。这更多来自一般的理论观点。)

我正在学习大学数据库,并且我已经了解到SQL数据库为了执行查询,首先将其转换为relational algebra,以便形成如何执行它的计划。关系代数使得表示非相关SQL子查询变得非常容易,然后我们可以根据需要将它们组合成连接或设置操作。例如,我们可以很容易地表达

SELECT y FROM Table WHERE y NOT IN (SELECT x FROM AnotherTable);

作为两个查询之间的集合差异。

然而,据我所知,关系代数没有提供表达相关子查询的SQL概念的机制,也没有提供从父查询中捕获列的查询,因此必须多次执行,例如本例下面:

SELECT employee_number, name
  FROM employees AS emp
  WHERE salary > (
    SELECT AVG(salary)
      FROM employees
      WHERE department = emp.department);

(在此示例中,外部WHERE子句中的子查询与员工的部门相关联,这意味着必须为每个员工运行一次子查询,以便按部门筛选结果。)

与许多其他相关子查询一样,可以通过使用连接和单个聚合查询来解相关此子查询,这将允许查询在RA中完全可表达并且还使子查询仅运行一次:

SELECT emp.employee_number, emp.name
  FROM employees AS emp
  JOIN (
    SELECT department AS department, AVG(salary) AS avg_salary
    FROM employees
    GROUP BY department) AS salaries
    ON emp.department = salaries.department
  WHERE emp.salary > salaries.avg_salary;

是否有可能将所有相关子查询表示为去相关子查询,以便将它们表示为关系代数,或者是否存在一些必须表达的相关子查询?换句话说,SQL关联只是一个便利功能,它不会为SQL的表达能力添加任何东西,或者RA只是一个实现指南,因为这个功能,SQL更具表现力吗?

如果是前者,这是什么证明/算法?如果是后者,是否有一种普遍接受的RA形式直接表达相关性?

2 个答案:

答案 0 :(得分:1)

我想在这里指出,你可能会误解到一个子查询到底是什么“相关”。

根据我的理解,如果子查询仅包含来自包含(/外部)查询的列,则子查询是“相关的”。您的SELECT AVG(...)查询不符合该描述。它就是所谓的标量子查询。因为它只会从某个表中计算标量值。它也可以“独立”。

至于实际问题,确定此特定查询的RA表示法的任何困难都是由于查询涉及聚合这一事实,并且RA表示法通常不支持表示此类操作。如果他们这样做了,原始表格与您的SELECT AVG(...)以及JOIN上所需的RESTRICT的JOIN将解决您的问题。

答案 1 :(得分:1)

首先,可以在关系代数和聚合中表达相关子查询(->依赖联接)。

您可能对此感兴趣:http://www.btw-2015.de/res/proceedings/Hauptband/Wiss/Neumann-Unnesting_Arbitrary_Querie.pdf

我还没有阅读整篇论文,但是我和Neumann教授一起上了课。他声称您可以取消关联任意查询。 但是我相信有一些限制。

select *
from T1
where T1.a = (select T2.a from T2 where T2.b = T1.b)

原则上,解相关该查询将很容易,在查看了查询计划后,我相信他们主持的数据库系统能够做到这一点(https://hyper-db.de/interface.html)。我认为您无法在SQL中表达这一点,因为如果子查询未返回标量(https://blogs.msdn.microsoft.com/craigfr/2006/09/27/scalar-subqueries/),则会在此出现运行时错误。