5 复杂查询
5.1 视图
1.表和视图的区别
表:保存的是实际的数据视图:保存的是SELECT语句。从视图读取数据时,视图会在内部执行该SELECT语句并创建出一张临时表。2.视图的优点
① 无需保存数据,因此可以节省存储设备的容量。② 可以将频繁使用的SELECT语句保存成视图。3.创建视图
CREATE VIEW 视图名称 (<视图列名1>,<视图列名2>,...)AS <select语句 style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">;CREATE VIEW ProductSum (product_type,cnt_product) AS SELECT product_type,COUNT(*) FROM Product GROUP BY product_type;
4.删除视图
DROP VIEW 视图名称;DROP VIEW ProductSum ;
5.多重视图
以视图为基础创建的视图;应避免使用,多重视图会降低SQL的性能。6.视图的限制
①定义视图时不能使用ORDER BY子句因为视图和表一样,数据行都是没有顺序的。②对视图进行更新必须满足一系列条件(既没有聚合又没有结合的SELECT子句),归根结底是对表的更新。1)SELECT子句中未使用DISTINCT2)FROM子句中只有一张表3)未使用GROUP BY 子句4)未使用HAVING 子句5.2 子查询
子查询的特点概括起来就是一张一次性视图。SELECT product_type,cnt_product FROM (SELECT product_type,COUNT(*) AS cnt_peoduct FROM Product GROUP BY product_type) AS ProductSum;
1.执行顺序
子查询作为内层查询会首先执行。2.增加子查询的层数
子查询的层数原则上没有限制,但是,随着子查询嵌套层数的增加,SQL语句会变得越来越难读懂,性能也越来越差。因此,应避免使用多层嵌套的子查询。3.子查询的名称
原则上子查询必须设定名称。4.标量(单一)子查询:返回单一值的子查询
必须只能返回一行一列的结果优点:标量子查询的返回值可以用=或<>这样需要单一值的比较运算符之中。
书写位置:能够使用常数或列名的地方,无论是SELECT子句,GROUP BY子句,HAVING子句,ORDER BY子句,几乎所有地方都可以使用。--在WHERE子句中不能使用聚合函数 SELECT product_id,peoduct_name,sale_price FROM Product WHERE sale_price > AVG(sale_price);
筛选价格处于上游的商品时,看似上述Sql语句可以满足我们的需求,但是WHERE子句中不能使用聚合函数,因此这样的Sql语句是错误的;这个时候标量子查询就可以发挥它的功效了。
SELECT product_id,peoduct_name,sale_price FROM Product WHERE sale_price > (SELECT AVG(sale_price) FROM Product);
5.3 关联子查询
- 关联子查询会在细分的组内进行比较时使用
- 关联子查询和GROUP BY子句一样,也可以对表中的数据进行切分
- 关联子查询的结合条件如果出现在子查询中就会发生错误
只通过语言描述可能难以理解,让我们看一下具体示例。按照商品种类与平均销售单价进行比较。
我们并不是要以全部商品为基础,而是要以细分的组为基础,对组内商品的平均价格和各商品的销售单价进行比较。--发生错误的子查询 SELECT product_id,peoduct_name,sale_price FROM Product WHERE sale_price > (SELECT AVG(sale_price) FROM Product GROUP BY product_type);
上述Sql出错的原因是因为该子查询会返回多行结果,并不是标量子查询。轮到关联子查询登场了。
SELECT product_id,peoduct_name,sale_price FROM Product AS p1 WHERE sale_price > (SELECT AVG(sale_price) FROM Product p2 WHERE p1.product_type = p2.product_type GROUP BY product_type);
这里起到关键作用的就是在子查询中添加的WHERE子句的条件,该条件的意思就是,在同一商品种类中对各商品的销售单价和平均单价进行比较。
组合条件一定要写在子查询中
--错误的关联子查询书写方式 SELECT product_id,peoduct_name,sale_price FROM Product AS p1 WHERE p1.product_type = p2.product_type WHERE sale_price > (SELECT AVG(sale_price) FROM Product p2 GROUP BY product_type);
该书写方式究竟违反了什么规则呢?