![26466cea47d3cfc91f25e1ac1f5e14e0.png](https://img-blog.csdnimg.cn/img_convert/26466cea47d3cfc91f25e1ac1f5e14e0.png)
内容简介:
- 视图
- 子查询
- 标量子查询
- 关联子查询
- 各种函数
- 练习题
- 总结
一.视图
1.1 视图是什么?
数据库里面有很多表,表里放的是实际数据,视图中存放的是SQL查询语句,当我们用客户端(例如navicat)连接到数据库使用视图的时候,视图会运行视图里面的SQL查询语句从表里面查询出数据保存到一张临时表里面,为什么叫临时表呢?因为当客户端与数据库的连接断开后这张临时表会被自动删除掉,所以他不是保存在数据库里的表,是临时的,所以叫临时表,所以,视图它本身不存放数据,它存放的是SQL查询语句
create view <视图名>(列名1,列名2,......)
as
(select 语句)
要注意的是,视图后面的列名 要于 select 后面的 列名 一一对应
creat view 按性别汇总 (性别,人数) as select 性别,count(*)as 人数 from student group by 性别;
![d87641248ad6aea506bd6973e0d5fd6b.png](https://img-blog.csdnimg.cn/img_convert/d87641248ad6aea506bd6973e0d5fd6b.png)
如何创建视图:
![c5689bd0da0768c55ff075f53074450e.png](https://img-blog.csdnimg.cn/img_convert/c5689bd0da0768c55ff075f53074450e.png)
- 删除视图:drop view<视图名>
- 视图的限制: 不能用order by 语句定义视图,没有经过聚合汇总,未使用distinct 的视图才 能进行刷新
1.2视图如何使用用?
select 性别,人数
from 按性别汇总; (用视图名称代替表名称)
![1f38ab897e9ca800551fc70777a36292.png](https://img-blog.csdnimg.cn/img_convert/1f38ab897e9ca800551fc70777a36292.png)
删除视图:客户端--视图---按性别汇总-删除(右键)
1.3 视图有什么用?
如果工作中要频繁使用某些查询 那就用视图保存数据 可以节省存放空间 尤其要运行复杂和运算量大的查询的时候 有了视图就能节省不少时间了
1.4 视图使用要注意什么?
1.避免在视图的基础上在创建视图,多重视图会降低SQL的性能和效率
2.不能忘视图里面插入数据,不然会报错
二.子查询
2.1 什么是子查询?
子查询是一次性的视图,在一个select 语句中再嵌套一个select查询语句
子查询是一次性的临时表 不像视图那样保存在硬盘里所以当SQL查询语句运行结束以后它就被清除掉了
当SQL查询语句里面有子查询的时候第一步会先运行子查询语句得到一张临时表,第二步将第一步运行到的结果将用于外部的查询语句中
2.2 如何使用自查询?
1.可以出现在from子句中,作为一个临时表使用
Select (列名) From (Select 列名From 表名)
举例:从该表中筛选出 总成绩大于240分的学生,成绩
思路:我们首先要汇总成每个学生sid的总成绩做为基础表(子查询),在从这个基础表里筛选出总成绩>240的记录; 代码如下:
select sid ,score_2
from
(select sid ,sum(score) as score_2
from sc
group by sid) t
where score_2 >240 ;
![34f0b04ecc5c2fabe0885d87dc76f6c9.png](https://img-blog.csdnimg.cn/img_convert/34f0b04ecc5c2fabe0885d87dc76f6c9.png)
- 2.子查询可以出现在Where子句中,作为过滤条件;(in ,any ,all)
where in (子查询)
举例 1:成绩在60分以上的学生ID 的 总成绩 ,
思路:我们要先选出成绩在60分以上的学生ID,在对这些ID的学生的成绩 进行汇总
select sid ,sum(score )
from sc
where sid in (select sid
from sc
where score >60)
group by sid;
where any(子查询),别担心,练习题里有案例
any和all :必须与比较运算符一起使用;
any (子查询) sum(子查询) 相同,满足子查询里面的人一个元素就可以
select 列名1 from 表名1 where 列名1>any (子查询);
![7aa5a6b07482ff7bd972044c395ab6ef.png](https://img-blog.csdnimg.cn/img_convert/7aa5a6b07482ff7bd972044c395ab6ef.png)
where any(子查询),别担心,练习题里有案例
where all all跟 any相反 要满足所有子查询里的条件
3.能够出现在select list中,作为一个字段值来返回
Select 列名, (Select 列名From 表名) From 表名 Where 列操作符
举例:学生的'01'课程成绩,总体成绩, 以及其占总体成绩的比例
select sid,cid ,score ,(select sum(score) from sc ) as total_score,
score /(select sum(score) from sc ) as rate
from sc
where cid ='01' ;
2.3子查询有什么用?
根据你的使用母的,频繁使用的查询可以用视图,偶尔使用的查询可以用子查询
2.4 子查询要注意什么?
尽量避免多层嵌套子查询
三.标量子查询
- 3.1 标量子查询是什么?
返回单一值且只能是但一值的子查询叫标量子查询
例如:我们会常常遇到这样的问题,求出平均成绩大于(60分)及格线的学生,看上去题面很简单啊,只需要 select sid from sc where avg(score)>60,你会发现报错; 因为where 语句不能做汇总查询,怎么办呢?这个时候就可以用到 标量子查询了
![d6754344cf5db82747b5f71252c8e29e.png](https://img-blog.csdnimg.cn/img_convert/d6754344cf5db82747b5f71252c8e29e.png)
- 3.2 标量子查询怎么使用?
where+标量子查询:
上述例子中只需要把代码调成成:
select distinct sid ,avg(score) from sc
where score >(select avg(score) from sc )
group by sid;
![619258933524b13eee664cbc8e8d7a3d.png](https://img-blog.csdnimg.cn/img_convert/619258933524b13eee664cbc8e8d7a3d.png)
select +标量子查询:
例子2.求每个学生的平均成绩、整体平均成绩成绩
select sid
,avg(score)
,(select avg(score) from sc ) as avg_2
from sc t1
group by sid;
![2eaabed3771b1cdf1f995b3f75d9daeb.png](https://img-blog.csdnimg.cn/img_convert/2eaabed3771b1cdf1f995b3f75d9daeb.png)
- 3.3 标量子查询有什么用?
普通的子查询返回的是多行值或者单一值,标量子查询是但一直且只能是但一直,
因为返回的是单一的值,所以可以跟运算符一起使用(in ,any, all,between )实现复杂的查询。
- 3.4 标量子查询应注意什么?
标量子查询不能求多行值,
图中的例子 子查询错误原因是,用group by 后 其结果会查询出多行值;
![635d0afb54387fcb44bb55f7b64179c7.png](https://img-blog.csdnimg.cn/img_convert/635d0afb54387fcb44bb55f7b64179c7.png)
四.关联子查询
- 4.1关联子查询是什么?
我们会遇到组内查询的情况:查询出 每个课程中大于该课程平均成绩的学生
![7d0b3a28640419284eb7260f4cabae20.png](https://img-blog.csdnimg.cn/img_convert/7d0b3a28640419284eb7260f4cabae20.png)
![0bca761ed9834e43b94b1df351c68717.png](https://img-blog.csdnimg.cn/img_convert/0bca761ed9834e43b94b1df351c68717.png)
解题思路:
- 我们要在01课程这个组里筛选出成绩大于 变量1(01课程的平均成绩64.5 )的学生;
- 我们要在02课程这个组里筛选出成绩大于 变量2(02课程的平均成绩72.66)的学生;
- 我们要在03课程这个组里筛选出成绩大于 变量3(03课程的平均成绩68.5)的学生;
这种情况下就要用到关联子查询了。
- 4.2 关联子查询怎么使用?
select <列名1>,<列名2>
from <表名> as <主查询名>
where <列名> =(select <列名>
from <表名> as <子查询名>
where <主查询名>.<列名>=<子查询名>.<列名>);
每个课程中 高于课程平均成绩的 学生sid 、cid、score
select cid,sid,score
from sc t1
where score> (select avg(score)
from sc t2
where t1.cid=t2.cid
group by cid)
group by cid ,sid ;
![542ff8681eecf5811ada7cd3d821bfb1.png](https://img-blog.csdnimg.cn/img_convert/542ff8681eecf5811ada7cd3d821bfb1.png)
- 4.3 关联子查询有什么用?
在每个组里进行组内行比较
五.各种函数
函数的用处不言而喻,我们先简单了解下函数,以后的应用中慢慢涉及
常用的函数有:汇总函数,算术函数,字符串函数,日期函数
![d2a66689301b0c4095f37b4553159b7d.png](https://img-blog.csdnimg.cn/img_convert/d2a66689301b0c4095f37b4553159b7d.png)
![3ef82e3d1808dc1ff0cdbe5010fc7926.png](https://img-blog.csdnimg.cn/img_convert/3ef82e3d1808dc1ff0cdbe5010fc7926.png)
![cbe54ff0d0b3e85df04a24339e3f09d9.png](https://img-blog.csdnimg.cn/img_convert/cbe54ff0d0b3e85df04a24339e3f09d9.png)
![899f68eb4cabf3028483d1c9829480ad.png](https://img-blog.csdnimg.cn/img_convert/899f68eb4cabf3028483d1c9829480ad.png)
六.练习题
网址:https://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial;
1.列出每個國家的名字name,當中人口population是高於俄羅斯'Russia'的人口。
SELECT name FROM world
WHERE population >
(SELECT population FROM world
WHERE name='Russia')
2.列出歐州每國家的人均GDP,當中人均GDP要高於英國'United Kingdom'的數值。
用到了标量子查询,先找出英國'United Kingdom'的人均GDP(单一值): (select gdp/population from world where name='United Kingdom') ;在用这个GDP的值做为筛选条件进行查询
select name from world
where continent = 'Europe' and gdp/population >
(select gdp/population
from world
where name='United Kingdom');
3.在阿根廷Argentina及 澳大利亞Australia所在的洲份中,列出當中的國家名字name及洲分continent。按國字名字順序排序
select name , continent
from world
where continent in (select continent
from world
where name in ('Argentina','Australia'))
order by name;
4.哪一個國家的人口比加拿大Canada的多,但比波蘭Poland的少?列出國家名字name和人口population 。
select name ,population
from world
where population >(select population
from world
where name = 'Canada')
and
population <(select population
from world
where name = 'Poland');
5.Germany德國(人口8000萬),在Europe歐洲國家的人口最多。Austria奧地利(人口850萬)擁有德國總人口的11%。
顯示歐洲的國家名稱name和每個國家的人口population。以德國的人口的百分比作人口顯示。
select name ,concat(round(population/(select population from world where name = 'Germany')*100,0),'%')as rate
from world
where continent = 'Europe';
6.哪些國家的GDP比Europe歐洲的全部國家都要高呢? [只需列出name。] (有些國家的記錄中,GDP是NULL,沒有填入資料的。)
SELECT name
FROM world
WHERE GDP > ALL(SELECT GDP
FROM world
WHERE continent = 'Europe' AND GDP >0)
7.在每一個州中找出最大面積的國家,列出洲份continent, 國家名字name及面積area。 (有些國家的記錄中,AREA是NULL,沒有填入資料的。) -
SELECT continent ,name, area FROM world x
WHERE area >= ALL
(SELECT area FROM world y
WHERE y.continent=x.continent
AND area>0)
8.列出洲份名稱,和每個洲份中國家名字按子母順序是排首位的國家名。(即每洲只有列一國)
字符串排序用A-Z的顺序 做为大小排序
select continent,name
from world s1
where name <= all(select name from world s2 where s1.continent=s2.continent)
9.找出洲份,當中全部國家都有少於或等於 25000000 人口. 在這些洲份中,列出國家名字name,continent洲份和population人口。
select name, continent, population
from world as A
where 25000000 >= all
(select population
from world as B
where A.continent=B.continent);
10.有些國家的人口是同洲份的所有其他國的3倍或以上。列出 國家名字name 和 洲份 continent。
SELECT name ,continent
from world A
where population >=all (select 3*population from world B
where A.continent=B.continent and A.name <> B.name);
七.总结:
![6b06a234dc829d84eeb0b74ac5392709.png](https://img-blog.csdnimg.cn/img_convert/6b06a234dc829d84eeb0b74ac5392709.png)