欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mysql中视图

程序员文章站 2022-06-02 08:59:27
...

mysql中视图

直接po代码

#视图
/*

含义:虚拟表,和普通表一样使用
mysql5.1版本出现的新特性,是通过表动态生成的数据

比如:舞蹈班和普通班级的对比

视图和表的对比
	创建语法的关键字	是否实际占用物理空间	           使用
视图	create view		只是保存了sql逻辑	增删改查,只是一般不能增删改
表	create table		保存了实际具体的数据		 增删改查


*/
USE student;

#案例:查询姓张的学生名和专业名
SELECT studentname,majorname
FROM student s
INNER JOIN major m ON s.majorid = m.majorid
WHERE s.studentname LIKE '张%';

#创建视图(小试牛刀)
CREATE VIEW stuAndMajor
AS
SELECT studentname,majorname
FROM student s
INNER JOIN major m ON s.majorid = m.majorid;

#使用视图
SELECT * FROM stuAndMajor WHERE studentname LIKE '张%';

#
USE myemployees;
#一、创建视图
/*
语法:
create view 视图名
as
查询语句;

*/

#1.查询姓名中包含a字符的员工名、部门名和工种信息
#创建视图
CREATE VIEW myView1
AS
SELECT `last_name` AS 员工名, `department_name` AS 部门名, `job_title` AS 工种名
FROM `employees` AS emp INNER JOIN `departments` AS dep
ON emp.`department_id` = dep.`department_id`
INNER JOIN `jobs` AS j
ON emp.`job_id` = j.`job_id`;
#where last_name like '%a%';


#使用视图(有效果,能查出数据)
SELECT * FROM myView1 WHERE 员工名 LIKE '%a%';

#使用视图(无效果且还报错,不存在last_name列,原因是创建视图时给last_name列起了别名)
SELECT * FROM myView1 WHERE last_name LIKE '%a%';


#2.查询各部门的平均工资级别
CREATE VIEW myView2
AS
SELECT department_id, AVG(salary) AS ag FROM employees emp
GROUP BY department_id;

#使用视图
SELECT department_id, ag, gra.`grade_level` FROM myView2 AS myV
INNER JOIN job_grades AS gra
ON myV.`ag` BETWEEN gra.`lowest_sal` AND gra.`highest_sal`;

#也可以如下写法(会晕死,查询语句没问题却总是报错,在网上查了下原因,mysql视图中是不可以使用子查询的)
#既然mysql视图中不支持子查询,我们可以拆分成多个视图,再将多个视图关联成一个大的视图(即移花接木)
CREATE VIEW myView3
AS
SELECT avg_dep.*, gra.`grade_level` FROM (
SELECT department_id, AVG(salary) AS ag
FROM employees emp
GROUP BY department_id) AS avg_dep
INNER JOIN job_grades gra
ON avg_dep.ag BETWEEN gra.`lowest_sal` AND gra.`highest_sal`;
#

#创建视图1
CREATE VIEW myV_avg_dep
AS
SELECT department_id, AVG(salary) AS ag
FROM employees emp
GROUP BY department_id;

#创建视图2
CREATE VIEW myV_grades
AS
SELECT * FROM job_grades;

#使用视图
SELECT myV_avg_dep.*, myV_grades.grade_level FROM myV_avg_dep INNER JOIN 
myV_grades
ON myV_avg_dep.ag
BETWEEN myV_grades.lowest_sal AND myV_grades.highest_sal;

#创建视图
CREATE VIEW myView3
AS
SELECT myV_avg_dep.*, myV_grades.grade_level FROM myV_avg_dep INNER JOIN 
myV_grades
ON myV_avg_dep.ag
BETWEEN myV_grades.lowest_sal AND myV_grades.highest_sal;

#使用视图
SELECT * FROM myView3;


#3.查询平均工资最低的部门信息
SELECT * FROM myView2 ORDER BY ag ASC LIMIT 0, 1;
SELECT * FROM myView2 ORDER BY ag ASC LIMIT 1;




#4.查询平均工资最低的部门名和工资
CREATE VIEW myView4
AS
SELECT * FROM myView2 ORDER BY ag ASC LIMIT 1;

#
SELECT dep.*, m.ag FROM myView4 m
INNER JOIN departments dep 
ON m.department_id = dep.department_id;


#二、视图的修改

#方式一:
/*
create or replace view  视图名
as
查询语句;

*/
SELECT * FROM myView4;

#修改视图
CREATE OR REPLACE VIEW myView4
AS
SELECT job_id, AVG(Salary) FROM employees
GROUP BY job_id;

#方式二:
/*
语法:
alter view 视图名
as 
查询语句;

*/

#修改视图
ALTER VIEW myView4
AS
SELECT * FROM employees;

#三、删除视图
/*

语法:drop view 视图名,视图名,...;

注意:前提是必须有该视图的drop权限
*/
#一次删除一个视图
DROP VIEW myview2;
#一次删除多个视图
DROP VIEW myview3, myview4;
#
DROP VIEW IF EXISTS myview3, myview4;


#四、查看视图
DESC myView4;
#查询某个视图的定义
SHOW CREATE VIEW myView4;


#创建视图
CREATE VIEW testView1
AS
SELECT COUNT(*) FROM employees;

#查询视图
SELECT * FROM testView1;

#修改视图
CREATE OR REPLACE VIEW testView1
AS
SELECT AVG(salary) FROM employees;

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

#二、创建视图emp_v2,要求查询部门的最高工资高于12000的部门信息
#创建视图
CREATE OR REPLACE VIEW max_sal_dep
AS
SELECT MAX(salary) max_sal ,department_id FROM employees
GROUP BY department_id
HAVING max_sal > 12000;

#创建视图
CREATE OR REPLACE VIEW emp_v2
AS
SELECT max_sal_dep.max_sal, dep.* FROM departments AS dep
INNER JOIN max_sal_dep
ON dep.department_id = max_sal_dep.department_id;

#使用视图(移花接木)
SELECT * FROM emp_v2;


#注意:mysql中,视图不支持子查询(虽然不支持子查询,但是我们可以移花接木)
CREATE OR REPLACE VIEW emp_v2
AS
SELECT max_sal_dep.*, dep.* FROM departments AS dep
INNER JOIN
(SELECT MAX(salary) AS max_sal ,department_id FROM employees
GROUP BY department_id
HAVING max_sal > 12000) max_sal_dep
ON dep.department_id = max_sal_dep.department_id;

#
#
SELECT * FROM my_employees;
INSERT INTO my_employees(last_name, userid) VALUES('段誉', 5);

#
SHOW VARIABLES LIKE  'autocommit%';

#五、视图的更新(指的是对视图的数据的更新)

DESC book;
DESC booktype;
SHOW CREATE TABLE book;
ALTER TABLE book MODIFY COLUMN bid INT AUTO_INCREMENT;
#
SELECT * FROM book;
SELECT * FROM booktype;

#创建视图(这是一个超级简单的视图)
CREATE OR REPLACE VIEW v1
AS
SELECT bName, price FROM book;

#使用视图
SELECT * FROM v1;

#
DESC book;
#
SELECT * FROM book;


/*
注意:对于特别简单的视图,是可以更新视图中的数据的,但是对于复杂的视图,是没办法更新视图中的数据的,
如果对视图中的数据更新成功,那也会对原始表中的数据进行更新(即会影响原始表中的数据)
*/

#对一个超级简单的视图,插入数据,可以成功插入数据,同时原始表中也相应的插入了该条数据
#对视图进行插入数据的操作(下面这条sql语句,能更新视图中的数据,同时也更新了原始表中的数据)
#1.向视图中插入数据(成功向视图中插入数据,同时成功向原始表中插入数据)
INSERT INTO v1 VALUES('平凡的世界', 88.36);

#2.向视图中修改数据(视图中的数据修改成功,原始表中的数据也修改成功)
UPDATE v1 SET bName = '新笑傲江湖' WHERE bName = '笑傲江湖';


#3.向视图中删除数据(视图中的数据删除成功,原始表中的数据也删除成功)
DELETE FROM v1 WHERE bName = '平凡的世界';


#创建一个稍微复杂一点的视图
CREATE OR REPLACE VIEW v2
AS
SELECT bName, price, price * 5 AS myTest FROM book;
#查看视图
SELECT * FROM v2;

#向视图中插入数据(向视图中插入数据失败)对于复杂的视图,是没办法更新视图中的数据的
INSERT INTO v2 VALUES('围城', 26.37, 135.67);


#以下情况不能对视图更新
/*
具备以下特点的视图不允许更新

1.包含以下关键字的SQL语句:分组函数、DISTINCT、GROUP BY、HAVING、UNION或者UNION ALL
2.常量视图
3.SELECT中包含子查询
4.JOIN
5.FROM一个不能更新的视图
6.WHERE子句的子查询引用了FROM子句中的表
等等等,可能还有其他情况,就不依次列举了

总之,对于特别简单的视图,是可以更新视图中的数据的,但是对于复
杂的视图,是没办法更新视图中的数据的

*/

#1.包含以下关键字的sql语句:分组函数、distinct、group  by、having、union或者union all
CREATE OR REPLACE VIEW v3
AS
SELECT MAX(price) m, bName
FROM book
GROUP BY bName;

#
SELECT * FROM v3;
#更新
UPDATE v3 SET m = 127.58 WHERE bName = '三国演义';

#2.常量视图
CREATE OR REPLACE VIEW v4
AS
SELECT '令狐冲' AS userName;

#
SELECT * FROM v4;

#更新
UPDATE v4 SET userName = '韦小宝';

#3.Select中包含子查询
CREATE OR REPLACE VIEW v5
AS
SELECT bName,(SELECT MAX(price) FROM book) AS max_price
FROM book;

#
SELECT * FROM v5;
#更新
UPDATE v5 SET max_price = 220.56;

#4.join
CREATE OR REPLACE VIEW v6
AS
SELECT bName,price,bt.name
FROM book b
JOIN bookType bt
ON b.bTypeId = bt.id;

#
SELECT * FROM v6;
SELECT * FROM book;
#更新可以成功,但是插入却是失败,我们统一认为该视图不能更新
#更新(更新成功)
UPDATE v6 SET bName = '新射雕英雄传' WHERE bName='射雕英雄传';
#插入(插入失败)
INSERT INTO v6 VALUES('水浒传', 55.36, '历史');

#5.from一个不能更新的视图
CREATE OR REPLACE VIEW v7
AS
SELECT * FROM v5;

#
SELECT * FROM v7;

#更新
UPDATE v7 SET max_price = 188.56 WHERE bName = '天龙八部';

#6.where子句的子查询引用了from子句中的表
CREATE OR REPLACE VIEW v8
AS
SELECT bName, price
FROM book
WHERE bid IN(
	SELECT bid
	FROM book
	WHERE price BETWEEN 100 AND 150
);

#
SELECT * FROM v8;
#更新
UPDATE v8 SET price = 89.76 WHERE bName = '三国演义';