4.7 SQL中的视图
在4.4.2节中简单介绍过视图的概念,在本节中会讨论数据定义语言对视图的操作。因为在定义视图时需要用到查询语句,所以在上面两节讲解查询语句后再来讨论视图的定义。
4.7.1 定义和删除视图
1.定义视图
定义视图使用语句CREATE VIEW,其语法格式为:
CREATE VIEW <视图名>[(<视图列表>)] AS <子查询>
其中,<视图列表>为可选项,省略时,视图的列名由子查询的结果决定。以下两种情况下,视图列名不可省略:
● 视图由多个表连接得到,在不同的表中存在同名列,则需指定列名;
● 当视图的列名为表达式或聚集函数的计算结果时,而不是单纯的属性名时,则需指明列名。
<子查询>可以是任何复杂的SELECT语句,但是在<子查询>中一般不许使用ORDER BY子句和DISTINCT短语,如果需要排序,则可在视图定义后,对视图查询时再进行排序。
例如,建立英语系学生的视图,使用的SQL语句如下:
CREATE VIEW ENGSTU AS SELECT SNO,SNAME,SSEX,SAGE FROM STUDENTS WHERE SDEPT='English';
新建的视图名为ENGSTU,语句中省略了视图列表,所以视图的列就由SELECT查询子句来决定。
视图创建后,只在数据字典中存放视图的定义,而其中的子查询SELECT语句并不执行。只有当用户对视图进行操作时,才按照视图的定义将数据从基本表中取出。下面再举几个例子说明CREATE VIEW语句的使用。
例如创建一学生情况视图S_SC_C(包括学号、姓名、课程名及成绩)。使用的SQL语句如下:
CREATE VIEW S_SC_C(SNO,SN,CN,SCORE) AS SELECT S.SNO,SN,CN,SCORE FROM S,C,SC WHERE STUDENTS.SNO=SC.SNO AND SC.CNO = COURSE.CNO;
此视图由三个表连接得到,在STUDENTS表和SC表中均存在SNO列,则需指定视图列名。如果还需要创建学生平均成绩的视图,则使用的SQL语句如下:
CREATE VIEW S_AVG(SNO,AVG) AS SELECT SNO,AVG(GRADE) FROM SC GROUP BY SNO;
此视图的第二个列使用了聚集函数,所以也必须指定视图的列名。
2.删除视图
视图定义后可随时删除,删除视图的语法格式为:
DROP VIEW <视图名>;
视图删除后,只会删除该视图在数据字典中的定义,而与该视图有关的基本表中的数据不会受任何影响,由此视图导出的其他视图的定义不会删除,但已无任何意义。用户应该把这些视图删除。
例如删除学生平均成绩视图的SQL语句如下:
DROP VIEW S_AVG;
4.7.2 查询视图
视图定义后,对视图的查询操作如同对基本表的查询操作一样。例如要查询学号为0406321的学生的平均成绩,SQL语句如下:
SELECT SNO,AVG FROM S_AVG WHERE SNO='0406321';
此查询的执行过程是系统首先从数据字典中找到S_AVG的定义,然后把此定义和用户的查询结合起来,转换成等价的对基本表SC的查询,这一转换过程称为视图消解(View Resolution),相当于执行以下查询:
SELECT SNO,AVG(GRADE) FROM SC WHERE SNO='0406321' GROUP BY SNO;
由上例可以看出,当对一个基本表进行复杂的查询时,可以先对基本表建立一个视图,然后只需对此视图进行查询,这样就不必再键入复杂的查询语句,而将一个复杂的查询转换成一个简单的查询,从而简化了查询操作。