四、SQL复杂查询

845 阅读4分钟

1、视图

1)视图的用处

视图本身不存放数据,它存放的是SQL查询语句
使用视图时,系统会运行视图里的SQL查询语句,创建出一张临时表。

2)创建视窗

create view 视图名称
as
<select 查询语句>

举例:

create view 按性别汇总(性别,人数) -- “按性别汇总”是视图名称
as
select 性别,count(*) -- select子句与create子句的列要一一对应,命名可以不同
from student
group by 性别;

3) 使用视图

在from子句中使用视图名称来代替表的名称

select 性别,人数
from 按性别汇总; -- 使用方法:在from子句中用视图名称代替表的名称

4)视图的意义

如果某些SQL语句需要频繁地使用,就可以将其保存成视图,如此一来就不用每次需要用到的时候都写一次。
使用视图的好处:
(1)在进行汇总以及复杂的查询条件导致SQL语句非常庞大的时候,使用视图可以提高效率
(2)视图中的数据可以随原表数据的更新而更新。
(3)视图不用保存数据,可以节省数据储存的空间。

5)注意事项

(1)避免在视图的基础上再创建视图,会降低SQL的性能和效率
(2)不能往视图中插入数据

2、子查询

1)什么是子查询?

子查询相当于在一个select查询语句中嵌套另一个select查询语句;相当于一个一次性的视图,在SQL查询结束之后就消失了。

注:当SQL语句中包含子查询时,会先运行子查询

SELECT 性别,人数
from(
select 性别,count(*) as 人数
from student
GROUP BY 性别

) as 按性别汇总;

2)如何使用子查询?

子查询可以在from子句中,也可以在where子句中,与运算符in、any(some)、all一起使用,构建出复杂的查询条件

练习1:哪些学生的成绩比课程0002的全部成绩里的任意一个高呢?

SELECT 学号,成绩
from score
where 成绩 > any(
SELECT 成绩
from score
where 课程号='0002'
)

练习2:哪些学生的成绩比课程0002的全部成绩里的都高呢?

SELECT 学号,成绩
from score
where 成绩 > **all**(
SELECT 成绩
from score
where 课程号='0002'
)

3)子查询的用处

偶尔使用时可以用子查询;如果是频繁使用就可以选择视图

4)使用子查询的注意事项

(1)书写规范
错误写法:a>3*all(b) ;因为all后面接的是一个集合,无法运用算术运算符
正确写法:a/3 > all(b)
(2)避免使用多层嵌套子查询;会使语句过于复杂而难以维护
(3)子查询中的 as 子查询名称 这部分是可以省略的

3、标量子查询

1) 标量子查询的定义

标量子查询只能返回一行一列的结果,不像子查询那样能返回一个集合。在任何需要使用单一值的位置,都可以使用标量子查询

2) 使用场景

由于在where子句中不能使用汇总函数,在某些情况下需要用到标量子查询来进行辅助。

练习1、:查找出成绩大于平均成绩的学生学号和成绩

SELECT 学号,成绩
from score
where 成绩 >(
SELECT avg(成绩)
FROM score
)

练习2:将成绩<=60的学生定义为差生,成绩>=80的学生定义为优等生,现在需要找出成绩介于优等生和差生平均成绩的学生学号和成绩

SELECT 学号,成绩
FROM score
where 成绩 between(
select avg(成绩)
from score
where 成绩<=60
) and(
SELECT avg(成绩)
FROM score
where 成绩>=80
)

3)标量子查询的作用

在需要多个值(即集合)时使用子查询
在需要单个值时使用标量子查询

4、关联子查询

需要在每个组内进行比较的时候,使用关联子查询;使用关联条件使数值对应起来

练习:查找出每个课程中大于对应课程平均成绩的学生

SELECT 学号,成绩
from score as s1
where 成绩>(
SELECT avg(成绩)
from score as s2
WHERE s1.课程号=s2.课程号
GROUP BY 课程号
)

5、扩展(SQL中的函数)

1)汇总函数

sum()、count()、avg()、max()、min()

2)算术函数

round()、abs()、mod() image.png

3)字符串函数

image.png

4)日期函数

image.png