SQL相关子查询是什么?和嵌套子查询有什么区别?

二者的各类叫法

  • 相关子查询叫作:Correlated Subqueries
  • 非相关子查询也叫普通子查询或嵌套子查询:Nested SubQueries

相关子查询MySQL解释

相关子查询是一个子查询中引用了某张表且这张表也在子查询外部被使用到。好比:html

SELECT * FROM t1
WHERE column1 IN (
    SELECT column1 FROM t2
    WHERE t2.column2 = t1.column2);

请注意子查询有一个t1表column2的引用,尽管子查询的from语句中没有涉及t1表,这时mysql执行子查询却发现t1表在外部查询中。mysql

假设表t1有一行数据(column1=5,column2=6),与此同时表t2有一行数据(column1=5,column2=7)。sql

若是是简单的子查询:性能

... WHERE column1 = ANY (SELECT column1 FROM t2)

结果将会是true,有数据返回。可是在这个例子中,where子句中的子查询会返回false,查不到任何数据,由于两张表的column2不匹配。code

相关子查询普通子查询(也叫非相关子查询)的差异就在于这子查询中是否有对外部查询中涉及到的表的引用。htm

规则范围: MySQL从内到外执行执行。好比:ip

SELECT column1 FROM t1 AS x
  WHERE x.column1 = (SELECT column1 FROM t2 AS x
    WHERE x.column1 = (SELECT column1 FROM t3
      WHERE x.column2 = t3.column1));

在这条语句中,x.column2必定是表t2的列,由于查询SELECT column1 FROM t2 AS x ...别名是x,它不是表t1的列是由于SELECT column1 FROM t1 ...是一个外部查询。它俩中间还隔着一对圆括号。get

相关子查询Wikipedia解释

相关子查询是使用外部查询中的值的子查询(嵌套在另外一个查询中的查询)。由于子查询需为外部查询返回的每一行执行一次,因此它可能会很慢。io

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

在上面的查询中,外部查询为:class

SELECT employee_number, name
   FROM employees emp
   WHERE salary > ...

内部查询(相关子查询)为:

SELECT AVG(salary)
   FROM employees
   WHERE department = emp.department

在上面的嵌套查询中,须为每一个员工从新执行内部查询。

相关子查询执行步骤拆解

看完官方和Wiki的解释,对相关子查询的描述基本同样,用本身的话说就是:

相关子查询被用来作逐行的处理,子查询会为外部查询出来的每一行执行内部SQL。(外部语句也可为update或delete语句)

可拆分红下面三个步骤:

  • 外部查询拿到全部行
  • 内部查询使用外部查询出来的每一行来执行本身逻辑
  • 内部查询有结果返回则当前外部行被保留最终返回不然继续执行下一行

相关子查询和嵌套查询的区别

  • 执行顺序:相关子查询是由外部查询驱动内部查询。 而正常的嵌套查询中,内部查询首先被当即执行,返回的值被外部查询使用并执行外部查询。
  • 依赖性:相关子查询内部查询依赖于外部查询进行处理,而在嵌套查询中外部查询依赖于内部查询。
  • 性能:使用相关子查询会使性能下降,由于它执行的次数远远大于嵌套查询的次数

参考资料

相关文章
相关标签/搜索