3.8.5 from子句中的子查询
SQL
允许在from
子句中使用子查询表达式。因为任何select-from-where
表达式返回的结果都是关系
,所以子查询
可以被插入到另一个select-from- where
中任何关系可以出现的位置。
SQL查询 找出系平均工资超过42000美元的那些系中教师的平均工资
考虑査询”找出系平均工资超过42000美元的那些系中教师的平均工资“。在3.7节我们使用了having
子句来书写此查询。现在我们可以不用having
子句来重写这个查询,而是通过如下这种在from
子句中使用子查询的方式:
1 | select dept_name,avg_salary |
1 | mysql> select dept_name,avg_salary |
子查询:
1 | ( select dept_name, avg(salary) as avg_salary |
产生的关系包含所有系的名字和相应的教师平均工资。子查询的结果属性可以在外层查询中使用.
注意我们不需要使用having
子句,因为from
子句中的子查询计算出了每个系的平均工资,早先在having
子句中使用的谓词现在出现在外层查询的where
子句中。
重命名from子查询的结果关系
我们可以用as
子句重命名子查询的结果关系,也可以使用as子句重命名子查询的属性
1 | select dept_name,avg_salary |
数据库实现对from子查询的支持
很多(但并非全部)SQL
实现都支持在from
子句中嵌套子查询。
请注意,某些SQL
实现要求对每一个from
子查询结果关系都给一个名字,即使该名字从不被引用;(MySQL
)
MySQL必须给from自己的子查询取别名
经过我的测试MySQL
必须对from
子查询的结果关系取别名,不给子查询取别名会报错:Every derived table must have its own alias
:
1 | mysql> select dept_name,avg_salary |
SQL查询 找出在所有系中工资总额最大的系
作为另一个例子,假设我们想要找出在所有系中工资总额最大的系。在此having
子句是无能为力的,但我们可以用from
子句中的子查询轻易地写出如下查询
1 | select max(tot_salary) |
1 | select max(tot_salary) |
我们注意到在from
子句嵌套的子查询中不能使用来自from
子句其他关系的相关变量。
子查询访问外层查询的相关变量 lateral关键词
然而SQL2003
允许from
子句中的子查询用关键词lateral
作为前缀,以便访问from
子句中在它前面的表或子查询中的属性。
例如,如果我们想打印每位教师的姓名,以及他们的工资和所在系的平均工资,可书写查询如下:
1 | select name, salary, avg_salary |
没有lateral
子句的话,子查询就不能访问来自外层查询的相关变量I1
。
数据库实现支持
目前只有少数SQL
实现支持lateral
子句,比如IBM DB2
原文链接: 3.8.5 from子句中的子查询