MySql的回顾十一:视图

  灵明无著,物来顺应,未来不迎,当下不杂,既过不恋,是之谓虚而已矣,是之谓诚而已矣。

  8月的处暑渐渐离我们远去,天气一天天的凉了起来,希望我们的心也能跟着这天气渐渐凉下来,真正能做到上面这句话。

  接下来由我带领各位读者继续学习MySql的视图部分的内容。

视图的创建
视图:MySql从5.0.1版本开始提供视图功能。一种虚拟存在的表
行和列的数据来定义视图的查询中使用的表,并且是在使用视图的动态生成,只保存了SQL逻辑,
不保存查询结果。 应用场景: 多个地方用到同样的的查询结果。 该查询结果使用的SQL语句教复杂。
先来一个案例领略一下视图的魅力。
#正常查询写法
查询姓张的同学与学科
SELECT s.studentname,m.majorname
FROM student s
INNER JOIN major m ON s.majorid = m.majorid
WHERE s.studentname LIKE '%张%';

#视图封装写法
CREATE VIEW shitu
AS
SELECT s.studentname,m.majorname
FROM student s
INNER JOIN major m ON s.majorid = m.majorid;

#运用视图(得到与上面图片一样的结果)
SELECT * FROM shitu WHERE studentname LIKE '%张%';

HeiDiSQL中创建视图

查看视图详情

#创建视图

语法:
CREATE VIEW 视图名
AS
查询语句
优点:
重用SQL语句
简化复杂的SQL的操作,不必知道它的查询细节
保护数据,提高安全性(隐藏原始表的信息)

#切换库
USE myemployees;
#1.查询邮箱中包含a字符的员工名,部门名和工种信息。
#1.正常查询方法
SELECT e.last_name,d.department_name,j.job_title,e.email
FROM employees e
INNER JOIN departments d
ON e.department_id=d.department_id
INNER JOIN jobs j
ON e.job_id=j.job_id
WHERE e.email LIKE'%a%';
#视图查询方法
#①创建视图 CREATE VIEW ayuan AS SELECT e.last_name,d.department_name,j.job_title,e.email FROM employees e INNER JOIN departments d ON e.department_id
=d.department_id INNER JOIN jobs j ON e.job_id=j.job_id;

#②使用视图查询
SELECT * FROM ayuan WHERE email LIKE '%a%';

#2.查询各部门的平均工资级别
#第一步创建视图,查出平均工资
CREATE VIEW pj
AS
SELECT ROUND(AVG(salary),2) ag,department_id
FROM employees
GROUP BY department_id;

#第二步连接查询
SELECT pj.ag,g.grade_level
FROM pj
INNER JOIN job_grades g
ON pj.ag BETWEEN g.lowest_sal AND g.highest_sal;

#3.查询平均工资最低的部门
#复用上一题的SQL语句逻辑,查出平均工资。
CREATE VIEW pj
AS
SELECT ROUND(AVG(salary),2) ag,department_id
FROM employees
GROUP BY department_id;
#查出最低工资
SELECT * FROM pj ORDER BY ag LIMIT 1;

#4.查询平均工资最低的部门名和工资
#思路1.视图也可以套视图
#1.第一步
CREATE VIEW pj2
AS
SELECT *
FROM pj
ORDER BY ag LIMIT 1;
#2.第二步
SELECT d.department_id,d.department_name,p.ag
FROM pj2 p
INNER JOIN departments d
ON p.department_id=d.department_id;

#思路2.复用第二题的SQL语句逻辑,查出平均工资
SELECT d.department_name,pj.ag,d.department_id
FROM pj
INNER JOIN departments d
ON pj.department_id=d.department_id
ORDER BY ag LIMIT 1;

视图的修改
修改视图:
语法方式一
CREATE OR REPLACE VIEW 视图名 AS 查询语句; 视图存在修改,视图不存在创建。 #示例:修改视图 #1.查看原视图 SELECT * FROM pj2; #2.修改视图 CREATE OR REPLACE VIEW pj2 AS SELECT AVG(salary),job_id FROM employees GROUP BY job_id;

修改视图
语法:方式二
ALTER VIEW 视图名
AS
查询语句;
只能修改,不能创建。

ALTER VIEW pj2
AS
SELECT * FROM employees;

删除视图
语法:
DROP VIEW 视图名,...;
可以一次性删除多个。

DROP VIEW pj,pj2;
查看视图结构
#第一种方式
DESC pj2;

#第二种方式:
完整的展示视图创建的语句(LINUX下查看) SHOW CREATE VIEW pj2;

案例:视图的创建
#一.创建视图emp_v1,要求查询电话号码以‘011’开头的员工姓名和工资,邮箱。
CREATE OR REPLACE VIEW emp_v1
AS
SELECT last_name,first_name,salary,email
FROM employees
WHERE phone_number LIKE '011%';
查看视图
SELECT * FROM emp_v1;

#二.创建视图emp_v2,要求查询部门的最高工资高于12000的部门信息。

#常规写法,第一步查出每个部门最高工资
SELECT MAX(salary) mx_dep,department_id
FROM employees
GROUP BY department_id
HAVING MAX(salary)>12000;
#第二步,查询最高工资高于12000的部门信息
SELECT d.*,m.mx_dep
FROM departments d
INNER JOIN (
SELECT MAX(salary) mx_dep,department_id
FROM employees
GROUP BY department_id
HAVING MAX(salary)>12000
) m
ON m.department_id=d.department_id;

#视图第一步,独立最高工资
CREATE OR REPLACE VIEW emp_v2
AS
SELECT MAX(salary) mx_dep,department_id
FROM employees
GROUP BY department_id
HAVING MAX(salary)>12000;

#视图第二步.视图也可以起别名
SELECT d.*,m.mx_dep
FROM departments d
INNER JOIN emp_v2 m
ON m.department_id = d.department_id;

视图的更新
(视图内的数据修改) #不能更新
/不是所有的视图都能更新 CREATE OR REPLACE VIEW myv1 AS SELECT last_name,email,salary*(1+IFNULL(commission_pct,0)) "annual salary" FROM employees;

#重新建立视图
CREATE OR REPLACE VIEW myv2
AS
SELECT last_name,email
FROM employees;

#1.插入数据

INSERT INTO myv2 VALUES('guangtouqiang','gtq@qq.com');
/* Affected rows: 1  Found rows: 0  Warnings: 0  Duration for 1 
query: 0.016 sec.
*/
受影响的行:1 找到的行:0 警告:0 1 查询的持续时间:0.016 秒。 #查看视图中的数据 SELECT * FROM myv2; SELECT * FROM employees; /数据插入成功后,视图与原始表会同时更新数据

#2修改数据
UPDATE myv2 SET last_name = '高仓健' WHERE last_name = 'guangtouqiang';

#查看视图中的数据
SELECT * FROM myv2;
SELECT * FROM employees;

#3.删除数据
DELETE FROM myv2 WHERE last_name = '高仓健';
/语句执行后,视图与原始表会同时删除数据/

#视图的可更新性和视图中查询的定义有关系,以下类型的视图是不能更新的。
发现包含以下的字段都是涉及到全表的数据,所以不允许修改。
包含以下关键字的SQL语句:分组函数,DISTINCT,GROUP BY,HAVING,
常量视图 UNION或者UNION ALL SELECT中包含子查询 JOIN FROM一个不能更新的视图 WHERE子句的子查询引用了FROM 子句中的表。

① #分组函数,新建视图
CREATE OR REPLACE VIEW myv1
AS
SELECT MAX(salary) M,department_id
FROM employees
ORDER BY department_id;

#查看视图
SELECT * FROM myv1;

② #常量视图
CREATE OR REPLACE VIEW myv2
AS
SELECT 'john' NAME;
SELECT * FROM myv2;

③ #SELECT中包含子查询
CREATE OR REPLACE VIEW myv3
AS
SELECT (SELECT AVG(salary) FROM employees) AS 平均工资;
SELECT * FROM myv3;

④ #JOIN
CREATE OR REPLACE VIEW myv4
AS
SELECT last_name,department_name
FROM employees e
INNER JOIN departments d
ON e.department_id=d.department_id;
SELECT * FROM myv4;

#更新
UPDATE myv4 SET last_name = 'GuangTouQiang' WHERE last_name='Fay';

虽然UPDATE没报错,但不能插入,统筹不能更新

⑤ #FROM一个不能更新的视图
CREATE OR REPLACE VIEW myv3
AS
SELECT (SELECT AVG(salary) FROM employees) AS 平均工资,department_id
FROM employees;
CREATE OR REPLACE VIEW myv5
AS
SELECT * FROM myv3;
SELECT * FROM myv5;

⑥ #WHERE子句的子查询引用了FROM 子句中的表。
CREATE OR REPLACE VIEW myv6
AS
SELECT last_name,email,salary
FROM employees
WHERE employee_id IN(
SELECT manager_id
FROM employees
WHERE manager_id IS NOT NULL
);
SELECT * FROM myv6;

#更新

 

  视图部分到此结束,希望看到这里的读者有所收,更多复杂而有趣的用法还需我们自己开动自己的大脑去带着手加以实践。

posted @ 2020-08-23 16:45  木卯生十木  阅读(301)  评论(0编辑  收藏  举报