SQL 查询视图

本文最后更新于:2024年3月18日 凌晨

SQL 查询视图

  • 视图定义后,用户就可以像对基本表一样对视图进行查询了。

[例3.92]:在信息系学生的视图中找出年龄小于20岁的学生。

1
2
3
SELECT Sno,Sage
FROM IS_Student
WHERE Sage<20;
  • 关系数据库管理系统执行对视图的查询时,首先进行有效性检查,检查查询中涉及的表,视图等是否存在,如果存在,则从数据字典中取出视图的定义,把定义中的子查询和用户的查询结合起来,转换成等价的对基本表的查询,然后再执行修正了的查询,这一转换过程称为视图消解(view resolution)
  • 本例转换后的查询语句为:
1
2
3
SELECT Sno,Sage
FROM Student
WHERE Sdept='IS' AND Sage<20;

[例3.93]:查询了选修1号课程的信息系学生。

1
2
3
SELECT IS_Student.Sno,Sname
FROM IS_Student,SC
WHERE IS_Student.Sno=SC.Sno AND SC.Cno='1';
  • 本查询涉及视图IS_Student(虚表)和基本表SC,通过这两个表的连接来完成用户请求。
  • 再一般情况下,视图查询的转换时直截了当的,但有些情况下,这种转换不能直接进行,查询时就会出现问题,如下例:

[例3.94]:在S_G视图(例3.89中定义的视图)中查询平均成绩在90分以上的学生学号和平均成绩,语句为:

1
2
3
SELECT *
FROM S_G
WHERE Gavg>=90;

例3.89中定义S_G视图的子查询为:

1
2
3
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;

将本例中的查询语句与定义S_G视图的子查询结合,形成下列查询语句:

1
2
3
4
SELECT Sno,AVG(Grade)
FROM SC
WHERE AVG(Grade)>=90
GROUP BY Sno;

因为WHERE子句中是不能用聚集函数作为条件表达式的,因此执行此修正后的查询将会出现语法错误,正确转换的查询语句应该是:

1
2
3
4
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=90;
  • 目前多数关系数据库对行列子集视图的查询均能进行正确转换,但对非行列子集视图的查询(如例3.94)就不一定能做转换了,因此这类查询应该直接对基本表进行。
  • 例3.94也可以用如下SQL语句完成:
1
2
3
4
5
6
SELECT*
FROM(SELECT Sno,AVG(Grade)/*子查询生成一个派生表S_G*/
FROM SC
GROUP BY Sno)
AS S_G(Sno,Gavg)
WHERE Gavg>=90;

但定义视图并查询视图与基于派生表的查询是有区别的,视图一旦定义,其定义将永久保存在数据字典中,之后的所有查询都可以直接引用该视图,而派生表只是在语句执行时临时定义,语句执行后该定义即被删除。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!