子查询就是一张一次性的视图。子查询就是将用来定义视图的select语句直接用于from子句当中。
create view ProductSum(product_type, cnt_product)
as
select product_type, count(*)
from Product
group by product_type;
以上创建的视图语句,可以用子查询来代替:
select product_type, cnt_product
from (select product_type, count(*) as cnt_product
from Product
group by product_type) as ProductSum;
结果是完全一样的。
子查询不会想视图那样保存在硬盘中,而是在select语句执行之后就消失了。
select语句查询的顺序,先执行括号内的内层子查询,再执行外层的select语句。
子查询在层数上没有限制,可以在子查询的from语句继续嵌套子查询:
select product_type, cnt_product
from (select *
from (select product_type, count(*) as cnt_product
from Product
group by product_type) as ProductSum
where cnt_product = 4) as productSum2;
随着子查询嵌套层数的增加,sql语句会变得难以读懂,性能也会越来越差,应避免使用。
标量子查询:顾名思义就是必须只能返回1行1列的结果,返回单一值的子查询。一般用于where等判断语句。
select product_id, product_name, sale_price
from Product
where sale_price > (select avg(sale_price)
from Product);
由于where子句不能判断聚会函数,可以使用标量子查询解决这个问题。
通过这个子查询得到一个唯一的平均数,与其销售价格进行比较。
标量子查询没有刻意控制书写位置,几乎所有的语句中都能使用:
select product_id, product_name, sale_price,
(select avg(sale_price)
from Product) as avg_price
from Product;
结果:
在having中使用:
select product_type, avg(sale_price)
from Product
group by product_type
having avg(sale_price) > (select avg(sale_price)
from Product);
该查询含义是想要选出按照商品种类计算出的销售单价高于全部商品的平均销售单价的商品种类。
标量子查询绝对不能返回多行结果。