CREATE VIEW ProductA (product_id, product_name, product_type, sale_price, purchase_price, regist_date)
AS
SELECT *
FROM Product
WHERE product_type = '办公用品';
向视图插入数据。
INSERT INTO ProductA VALUES ('0009', '铅笔', '办公用品', 95, 10, '2222-10-1');
此时可看到,视图和表都更新了。
删除视图:
格式
DROP VIEW 视图名称(<视图列名1>,<视图列名2>,...)
例子
DROP VIEW ProductSum;
然后报错
ERROR: cannot drop view productsum because other objects depend on it
描述: view productsuma depends on view productsum
提示: Use DROP ... CASCADE to drop the dependent objects too.
这是因为前面以ProductSum为基础,创建了一个ProductSumA视图。
可以像下面这样删除ProductSum和与之关联的视图。
DROP VIEW ProductSum CASCADE;
子查询
子查询,相当于一次性视图。
定义视图ProductSum
CREATE VIEW ProductSum (product_type, cnt_product)
AS
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type;
子查询:将定义视图的SELECT语句直接用到FROM子句里面。
AS ProductSum,ProductSum是子查询的名称。执行完外边的SELECT语句,子查询就消失了。
下面代码,执行顺序,先是FROM子句里面的SELECT语句,然后是外边的SELECT语句。
SELECT product_type, cnt_product
FROM (SELECT product_type, COUNT(*) AS cnt_product
FROM Product
GROUP BY product_type) AS ProductSum;
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;
标量子查询scalar subquery,返回表中某一行某一列的值(单一值)的子查询。
可以在WHERE子句中使用标量子查询。
由于WHERE子句中无法使用聚合函数,像下面的语句就是错误的。
SELECT product_id, product_name, sale_price
FROM Product
WHERE sale_price > AVG(sale_price);
可以通过下面这样去实现。
SELECT product_id, product_name, sale_price FROM Product WHERE sale_price > (SELECT AVG(sale_price) FROM Product);SELECT product_id, product_name, sale_price
FROM Product
WHERE sale_price > (SELECT AVG(sale_price)
FROM Product);
在任何使用单一值的地方,都可以使用标量子查询。
在SELECT子句中使用标量子查询:
SELECT product_id, product_name, sale_price, (SELECT AVG(sale_price) FROM Product) AS avg_price FROM Product;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);
SELECT AVG(sale_price)
FROM Product
GROUP BY product_type;
因为有三种商品,上面这个查询返回三个结果。
那么就不能用下面这种方法了。因为子查询不是标量子查询,不能在WHERE子句里面用。
SELECT product_id, product_name, sale_price
FROM Product
WHERE sale_price > (SELECT AVG(sale_price)
FROM Product
GROUP BY product_type);
在细分的组内进行比较的时候,用到关联子查询。
在子查询里面添加了一个WHERE子句。目的是在同一商品种类中对各商品销售单价和平均单价比较。
由于比较对象是同一个Product表,所以用了P1、P2两个别名。
使用关联子查询,用<表名>.<列名>形式,限定product_type,对平均单价比较。
SELECT product_type, product_name, sale_price
FROM Product AS P1
WHERE sale_price > (SELECT AVG(sale_price)
FROM Product AS P2
WHERE P1.product_type = P2.product_type
GROUP BY product_type);
而且,不加GROUP BY,也能得到相同结果:
SELECT product_type, product_name, sale_price
FROM Product AS P1
WHERE sale_price > (SELECT AVG(sale_price)
FROM Product AS P2
WHERE P1.product_type = P2.product_type);