原 SQL 学习整理
|-转 【知乎】从零学会SQL:复杂查询
内容太多了,还没来得及看,是想进一步学习SQL的,先在网上找些,有空时再仔细看 20200327 00:18从零学会SQL:复杂查询crazy1.视图1. 在实际的数据库中,每...
内容太多了,还没来得及看,是想进一步学习SQL的,先在网上找些,有空时再仔细看 20200327 00:18
crazy
1.视图
1. 在实际的数据库中,每一张表会有很多个字段,但是不同的用户只想了解自己想了解的字段,对于其他的字段并不感兴趣,这时候使用视图可以把自己想要的一些字段再封装成一张表,这样每次特定用户只需要访问这张封装成的表即可了解自己想知道的字段。再说的专业一点,视图是对SQL语句的封装,这个说法在下面进行解释
2. 视图是对SQL语句的封装。因为,我们在数据库中建立的一张张表会实际存储到存储设备上,比如磁盘,我们每次使用select语句,实际上就是在访问内存中的表,但是视图并不是,视图保存的并不是数据,而是select语句,每次从视图中读取数据的时候,相当于是在内部执行select语句并创建出一张临时表
3. 视图的优点:(1)视图不需要保存实际数据,节省存储空间(2)可以将频繁使用的select语句保存成视图,这样就不用每次都书写复杂的SQL了
/*
创建视图
create view 视图名称(<视图列名1>,<视图列名2>,...)
as
<select 查询语句>;
*/
create view 按性别汇总(性别,人数)
as
select 性别,count(*)
from student
group by 性别;
select*
from 按性别汇总; -- 在from子句中,使用视图名称代替表名称
-- 视图中存放的是sql查询语句,所以视图中的语句会随着原表的变化而更新,视图也不需要保存数据
-- 注意事项:避免在视图的基础上再去创建视图;不能往视图插入数据,否则会报错
2.子查询
嵌套SELECT语句也叫子查询,一个 SELECT 语句的查询结果能够作为另一个语句的输入值。子查询不但能够出现在Where子句中,也能够出现在from子句中,作为一个临时表使用,也能够出现在select list中,作为一个字段值来返回。
select 性别,人数
from (
select 性别,count(*) as 人数
from student
group by 性别 -- 先运行子查询
) as 按性别汇总;
select 性别,count(*) as 人数
from student
group by 性别;
-- in/any/all(子查询)
-- 找出每个课程里成绩最低的学号
-- 1.查找出每门课程的最低成绩有哪些值
select 课程号,min(成绩)
from score
group by 课程号;
-- 2.在成绩表里查找这些值对应的学号
select 学号,成绩
from score
where 成绩 in(80,50,40);
-- 这个可以显示正确的结果
select 学号,成绩
from score
where (课程号 =0001 and 成绩 =80) or (课程号 =0002 and 成绩 =50) or (课程号 =0003 and 成绩 =40);
select 学号,成绩
from score as s1
where 成绩 =(select min(成绩)
from score as s2
where s1.课程号 = s2.课程号 -- 在同一课程号中对各学号的成绩与最低成绩进行比较
group by 课程号);
-- 这个语句查询结果不太对,上面的两块代码可以正确显示每门课程里成绩最低的学号
select 学号,成绩
from score
where 成绩 in (
select min(成绩)
from score
group by 课程号
);
/*
any(子查询) 与some(子查询)相同
select 列名1
from 表名1
where 列名 > any(子查询);
*/
/*
哪些学生的成绩比课程0002的全部成绩里的任意一个高呢?
第一步:课程0002的全部成绩,比如是(10,30)
第二步:某个学生的成绩大于任何一个第一步里的成绩,就符合条件
*/
-- 第一步
select 成绩
from score
where 课程号 = '0002';
-- 第二步
select 学号,成绩
from score
where 成绩 > any(
select 成绩
from score
where 课程号 = '0002'
);
-- 哪些学生的成绩比课程0002的全部成绩都高呢?
select 学号,成绩
from score
where 成绩 > all(
select 成绩
from score
where 课程号 = '0002'
);
/*
使用子查询的注意事项
1.a>3*all(b)是错的,正确格式是a/3=all(b)
2.避免使用多层嵌套子查询
3.select...from...子查询 as 子查询名称(可省略)
*/
3.标量子查询
标量子查询就是返回值只能有一行一列的子查询...