今天的学习过程相对比较顺利,没有遇到什么过大的阻碍,现将我认为应该注意的知识点总结如下。
1.视图
视图是一个相对好理解的概念。我从人大张延松老师的书中摘抄了以下内容以解释视图:
- 视图是数据库从一个或者多个基本表导出的虚表,视图中只存储视图的定义,但是不存放视图对应的实际数据。
- 当访问视图时,通过视图的定义实时地从基本表中读取数据。定义视图为用户提供了基本表上多样化的数据子集,但不会产生数据冗余以及不同数据复本导致的数据不一致问题。
- 视图在定义后可以和基本表一样被查询、删除,也可以在视图上定义新的视图。
- 由于视图并不实际存储数据,视图的更新操作受到一定的限制。
在明确上述这几个要点后,我们就可以完成绝大多数对于视图的操作,而对于视图的定义和查询并不在我今天要讨论的范围之内,接下来我会尽可能说明关于视图更新的内容。
(1)单表上的视图更新
当一个视图仅基于单表选择、投影等方式创建时,在视图上执行更新操作则更多要参考基本表的定义和其约束。
当执行更新操作时,必须要遵守原表的约束条件,例如不能再唯一键列出现两个相同的值,不能将非空约束列的值改为NULL。
而在执行插入操作的时候,则更要关注主键等重要约束。
(2)单表上的聚集视图更新
当视图上存在COUNT(),SUM()等聚集操作的时候,就无法通过视图来修改表中数据,因为视图中的记录更新无法转换为等价的SQL命令,被数据库系统拒绝。
(3)多表连接视图更新
当视图由多个表连接而产生时,对其更新其实也类似于单表视图更新,只是要更加遵守外键等约束,对于不符合约束的更新,数据库是不可能接受的。
总的来说,大多数数据库通常支持以下视图的更新:
- FROM子句中只有一个基本表
- SELECT子句中只有基本表的属性,不包含任何表达式、聚集表达式或者DISTINCT声明
- 任何没有出现在SELECT子句中的属性都可以取空值
- 定义视图的查询不包含GROUP BY和HAVING子句
其实视图本身不是用于临时查询的,其更大的作用在于权限和数据管理方面,通过创建视图来保证底层数据的安全。如果仅仅是出于临时查询的需求,则应该使用临时表等方法,这样可以节约相当的资源。
2.IN
不得不说,IN是一个非常有用的谓词,在SQL语句中几乎无处不见,但是作为一个经常写SQL的人,我们要做到的不仅仅是能够查询到正确的结果,更要做到用更少的资源查询出对的结果。
。。。。迫于大作业,下次再完成。。。。
--附上本次作业代码
--3.1
CREATE VIEW ViewPractice5_1(product_name,sale_price,regist_date)
AS
SELECT product_name,sale_price,regist_date
FROM product
WHERE sale_price >= 1000 AND regist_date = '2009-09-20';
SELECT * FROM ViewPractice5_1;
--3.2
--无法插入,因为product_id是主键,不能有空值
--3.3
SELECT product_id,product_name,product_type,sale_price,(SELECT AVG(sale_price) FROM product) as sale_price_all
FROM product;
--3.4
CREATE VIEW AvgPriceByType(product_id,product_name,product_type_sale_price,avg_sale_price)
AS
SELECT product_id,product_name,product_type,sale_price,
(SELECT AVG(sale_price) FROM product p2 WHERE p1.product_type = p2.product_type) AS avg_sale_price
FROM product p1;
--3.5如果用一般的运算符与NULL进行运算,则结果会全部变为NULL。判断NULL应该使用IS NULL之类的谓词。
--3.6
--第一条语句能得到除NULL意外的正常的结果
--第二条语句查询结果为空
--3.7
SELECT SUM(CASE WHEN sale_price <= 1000 THEN 1 ELSE 0 END) AS '低档商品',
SUM(CASE WHEN sale_price > 1000 AND sale_price <= 3000 THEN 1 ELSE 0 END) AS '中档商品',
SUM(CASE WHEN sale_price > 3000 THEN 1 ELSE 0 END) AS '高档商品'
FROM product;
ALTER TABLE Orders_Returns ADD isReturned varchar(5);
UPDATE Orders_Returns set isReturned = (CASE WHEN Return_Reason is null THEN 'No' ELSE 'Yes' END);