课程地址:数据库 SQLServer 视频教程全集(99P)| 22 小时从入门到精通_哔哩哔哩_bilibili
目录
group by(分组)
group by a,b 的用法
having(对分组之后的信息进行过滤)
having和where的区别
总结
PPT内容总结与复习
函数的分类
聚合函数的使用
max() 函数
count() 函数
group by子句
聚合函数的错误用法
基于多个字段分组
having子句的用法
order by子句
select语句的执行顺序问题
select语句的基本结构
为什么select语句执行顺序很重要
select语句执行顺序
切换数据库也可以用SQL语句:use 数据库名称
输出每个部门的编号 和 该部门的平均工资
select deptno, avg(sal) as "部门平均工资" from emp group by deptno
判断下面语句是否正确
select deptno, avg(sal) as "部门平均工资", ename
from emp
group by deptno
-- 错误,前面两个字段都只有3行,第三个字段有14行(ename是组内详细信息)
一旦使用了group by,select后的字段只能写组的整体信息,不能写组内某个字段的详细信息
rollup 和 cube 查询
- group by cube(a,b,c) 统计结果等同于 group by(a)、group by(b)、group by(c)、group by(a,b)、group by(a,c)、group by(b,c)、group by(a,b,c)、group by() 结果的并集
总结:使用了group by之后,select中只能出现分组后的整体信息,不能出现组内的详细信息
以a和b整体为分组依据,组内的个体都是有着相同的a和b信息的
select deptno, job, sal from emp group by deptno, job -- error
select * from emp group by deptno, job -- error
select deptno, job, avg(sal) "平均工资", count(*) "人数", sum(sal) "总工资", min(sal) "最低工资"
from emp
group by deptno, job
order by deptno -- OK
select job from emp group by deptno, job -- OK
总结:
select comm, count(*) from emp group by comm
group by分组之后,count 也可以对 null 计数
输出部门平均工资大于2000的部门的部门编号、部门平均工资
select deptno, avg(sal) from emp group by deptno having avg(sal)>2000
判断下列SQL语句是否正确:
select deptno, avg(sal) as "平均工资" from emp
group by deptno having avg(sal)>2000 -- OK
select deptno, avg(sal) as "平均工资" from emp
group by deptno having "平均工资">2000 -- error
select deptno, avg(sal) as "平均工资" from emp
group by deptno having deptno>10 -- OK
select deptno, avg(sal) as "平均工资" from emp
group by deptno having count(*)>3 -- 按部门人数过滤也OK
select deptno, avg(sal) as "平均工资" from emp
group by deptno having ename like '%A%' -- error
把姓名不包含A(not like)的所有员工按部门编号分组,输出部门平均工资大于2000的部门的部门编号、部门平均工资
select deptno, avg(sal) "平均工资" from emp
where ename not like '%A%'
group by deptno
having avg(sal) > 2000
having与where都是对数据过滤,只保留有效的数据;且都不允许出现字段的别名,只允许出现最原始的字段的名字(SQL Server和Oracle都成立)
但存在以下区别:
所有select的参数的顺序是不允许变化的,否则编译时出错。where必须得写在having的前面,顺序不可颠倒,否则运行出错
select count(*) from emp having avg(sal)>1000
单行函数:对每一行记录都起作用,对每一行记录都能返回一个结果
多行函数:对一组记录返回一个结果,即对多行记录返回一个结果。聚合函数就是多行函数
例子:
注意0和null是两个不同的概念,个数包含comm为0的记录,但不包含comm为null的记录
用聚合函数作用某个字段时,会忽略掉所有的null行
用于对查询的结果分组统计
1、如果没有group by子句,select列表中不允许出现字段(单行函数)与分组函数混用的情况
select empno, sal from emp -- ok
select avg(sal) from emp -- ok
select lower(ename), sal from emp -- ok
select lower(ename), avg(sal) from emp -- error
2、不允许在where子句中使用分组函数,牵扯到select的执行顺序问题
3、出现在select列表中的字段,如果不是包含在分组函数中,那么该字段必须同时在group by子句中出现。但是包含在group by子句中的字段则不必须出现在select列表中
select avg(sal) from emp group by deptno -- ok
select deptno, avg(sal) from emp group by deptno -- ok
select ename, avg(sal) from emp group by deptno -- error
错误代码:
select deptno, job, ename, avg(sal) from emp group by deptno, job
-- select_list中不能出现ename字段
下述4个结论在SQL Server和Oracle中均成立:
select deptno from emp group by deptno having deptno > 10 -- ok
select deptno from emp having deptno > 10 -- error
-- Oracle和SQL Server是一样的,要使用having子句,都必须得先有group by子句
select max(sal) from emp having max(sal) = 5000 -- ok,结果为5000
select deptno, job, avg(sal) from emp
where hiredate >= '1981-05-01'
group by deptno, job
having sal > 1200 -- error,因为sal不是select_list中的
order by deptno, job
create table ST_CU
(
sid int, -- 学号
cid int, -- 课程号
score float -- 分数
)
insert into ST_CU values (1,1,66.6)
-- 查询学号为sid,课程为cid的学生的平均成绩
select sid, cid, avg(score) "平均分数"
from ST_CU
group by sid, cid
-- 查询学号为sid,课程为cid的学生这门课只考了两次的平均成绩
select sid, cid, avg(score) "平均分数"
from ST_CU
group by sid, cid
having count(score) > 2 -- 虽然select_list中没有,但是仍然正确
select deptno dt, job, avg(sal) as "avg_sal"
from emp
group by deptno, job
having avg(sal) = 5000 -- ok
having avg_sal = 5000 -- error
having "avg_sal" = 5000 -- error
having dt = 100 -- error
having deptno = 10 -- ok
如果不指定排序方式的话,默认是升序排序,升序用ASC表示
为某一个字段指定的排序方式并不会对另一个字段生效,强烈建议为每一个字段都指定排序方式
select * from emp order by deptno -- 按deptno升序,默认是升序
select * from emp order by deptno desc -- 按deptno降序
select * from emp order by deptno, sal desc -- 按deptno升序,再按sal降序
select语句基本结构中包含了8个子句,这些子句的排列顺序是固定的。其中除select子句外,其他子句都可省略,但若出现,则必须按照基本结构中的顺序排列
-- select语句的基本结构
select select_list
[into new_table_name]
from table_list
[where search_conditions]
[group by group_by_list]
[having search_conditions]
[order by order_list [ASC|DESC]]
例子:
select deptno, avg(sal)
from emp -- 从哪张表去查询
where sal > 2000 -- 对单条记录进行过滤
group by deptno -- 对数据进行分组
having avg(sal) > 1500 -- 对分组后的数据进行过滤
order by avg(sal) desc -- 对最后的结果进行排序
-- 错误的代码
select deptno, avg(sal) from emp
where avg(sal) > 2000
group by deptno
-- 原因
不允许在where子句中使用分组函数实例
先执行where,后执行group by,所以执行where时对emp表还没有进行分组,因此编译时会报错
select deptno, avg(sal) "平均工资", count(*) "部门人数", max(sal) "部门最高工资"
into emp_2
from emp
where sal > 2000 -- where是对原始记录过滤
group by deptno
having avg(sal) > 3000 -- 对分组之后的记录过滤
select deptno, job, avg(sal) from emp
where hiredate >= '1981-05-01'
group by deptno, job
having avg(sal) > 1200
order by deptno, job
注意: