mysql多行函数(聚合函数)

多行函数(聚合函数):
没分组,多行函数不能和其他普通字段一起查询;分组字段可以查询
(oracle直接报错,mysql执行结果是查询第一行的数据,结果毫无意义)  牢记!!!

  • sum()
  • avg()
  • max()
  • min()
  • count()

多个多行函数可以一起查询
select sum(sal),avg(sal),max(sal),min(sal),count(*) from emps;

多行函数会忽略null值

count(*) 记行数
count(distinct a) 去除重复再记数

group by子句 分组求多行函数
按指定字段中相同的值进行分组
分组后分别求多行函数
分组字段可以查询
group by a  按照a字段相同值进行分组
group by a,b  按照a,b组合的相同值进行分组(比较少见)


-- 每个部分的平均工资,并过滤掉dept_id为null的部门
先过滤,后分组
select dept_id,avg(sal) a from emps where dept_id is not null group by dept_id order by a;

-- 每个工作岗位job_id的人数
select job_id,count(*) from emps group by job_id;

-- 按主管id分组,求每个主管的手下人数
select mgr_id,count(*) from emps where mgr_id is not null group by mgr_id;


having子句
用来对多行函数结果,再进行过滤
执行顺序:where>group by>having>order by
having和where作用相同,都是条件过滤
where过滤"普通条件",最早执行
having过滤"多行函数结果",先分组group by,求完多行函数后,后执行having过滤
-- 按主管id分组,求出每个主管的手下人数为1的分组(只有一个手下的主管)
select mgr_id,count(*) from emps group by mgr_id having count(*)=1;
select mgr_id,count(*) c from emps group by mgr_id having c=1;
select mgr_id,count(*) c from emps where mgr_id is not null group by mgr_id having c=1 order by mgr_id desc;

-- 平均工资小于等于5000的岗位代码
select avg(sal) a,job_id from emps group by job_id having a<=5000;

子查询/查询嵌套
条件子查询
from子查询/行内视图
select子查询(较为少见)

条件子查询
一个查询的查询结果,作为另一个查询的过滤条件

单值子查询 =(select ...) >(select ...) >=(select ...) <(select ...) <=(select ...)
多值子查询 in(select ...)   >all(select ...) 比最大值大    >any(select ...) 比最小值大
多列子查询(a,b必须加小括号) where (a,b) in(select ...)      
where (a,b)=(select ...)      

-- 工资小于平均工资
select fname,sal from emps where sal<(
  select avg(sal) from emps
);

-- 每个部门拿最高工资的员工 (经典面试题)
select fname,sal,dept_id from emps where (dept_id,sal) in (
  select dept_id,max(sal) m from emps where dept_id is not null group by dept_id
) order by dept_id;  

-- 只有一个人的部门,查询这些员工(经典面试题)
方法:第一步,按部门分组求人数,过滤只有一人的部门
    select job_id from emps where dept_id is not null group by job_id having count(*)=1;
第二步,用部门id过滤查询员工
select fname,dept_id from emps where dept_id in (
  select dept_id from emps where dept_id is not null group by dept_id having count(*)=1
) order by dept_id;  

from子查询/行内视图
从查询的查询结果,再查询(此处mysql必须要别名,oracle不作要求)
-- 平均工资最低的工作岗位代码(经典面试题)三层嵌套
方法:第一步,按部门分组求平均工资
select job_id,avg(sal) a from emps group by job_id;
第二步,求平均工资最小值
select min(a) from (
    select job_id,avg(sal) a from emps group by job_id
) t;
第三步,用平均工资最小值,过滤岗位代码  重用第一步,设置having过滤
select job_id,avg(sal) a from emps group by job_id having a=(
    select min(a) from (
        select job_id,avg(sal) a from emps group by job_id
    ) t
);

oracle:  
select min(avg(sal)) from emps group by job_id; 
支持多行函数嵌套执行,
对from子查询/行内视图的结果,不需要别名
mysql:
不支持多行函数嵌套执行,
对from子查询/行内视图的结果,必须用别名才能查询

-- 手下人数最多的主管id
mgr_id  人数
20      7
30      11
50      11
80      11
90      10

方法:第一步,按mgr_id分组求人数(去除第一行凑巧结果order by c)
select mgr_id,count(*) c from emps where mgr_id is not null group by mgr_id order by c;

第二步,求人数的最大值11
select max(c) from(
    select mgr_id,count(*) c from emps where mgr_id is not null group by mgr_id order by c
) t;

第三步,用人数过滤查询主管id  重用第一步,设置having过滤
select mgr_id,count(*) c from emps where mgr_id is not null group by mgr_id having c=(
    select max(c) from(
        select mgr_id,count(*) c from emps where mgr_id is not null group by mgr_id order by c
    ) t
);
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值