sql - 是否可以取消关联所有相关的 SQL 子查询?

标签 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 形式?

最佳答案

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

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

我没有阅读整篇论文,但我参加了 Neumann 教授的类(class)。他声称你可以解除任意查询的关联。 但是,我认为存在一些限制。

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/),则会出现运行时错误。

关于sql - 是否可以取消关联所有相关的 SQL 子查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48692307/

相关文章:

php - 如何在 3 向 MYSQL 连接中检索以逗号分隔的链接 ID 列表?

javascript - 文本输入到种子随机数

algorithm - 旅行商问题中的交叉边

SQL 到关系代数

sql - 这个投影会返回什么?

c# - 如何在 C# 中使用 LINQ "select null as "列

mysql - 仅选择具有多个相同字段值的 4 条记录之一

windows - Linux Windows 之间的多任务、多线程有什么区别?

java - Armstrong Axioms 的所有属性都可以应用于多值依赖吗?

sql - 如何保护表以避免重复数据