现在有一个需求:
查询出员工的姓名、工资、部门编号和所在部门的平均工资,要求显示出来的是工资大于本部门平均工资的员工
用传统sql写法的思路是;
1、通过部门分组查找出来每个部门的平均工资和部门编号
2、查询每个员工的姓名、工资、部门编号
3、对上述个查询结果进行关联,关联结果为部门编号相等,并且员工工资大于本部门平均工资
加下来看sql
步骤1的sql
select deptno, AVG(sal) as AVL_sal,
from emp
group by deptno;
步骤2的sql
select ename, sal, deptno
from emp;
最后进行整合:
select t2.*, t1.AVG_sal
from
(select deptno, AVG(sal) as AVG_sal,
from emp
group by deptno )t1,
(select ename, sal, deptno
from emp) t2
where
t1.deptno = t2.deptno
and
t2.sal > t1.AVG_sal;
看似简单的一个需求却写出了这么复杂的sql,使我们开发路上的障碍。
加下来看用分析函数来实现本需求的分析:
使用:AVG(sal) over(partition by deptno) AVG_sal
我们可以直接得到每个部门的平均工资
partition by 相当于group by
只不过partition by 使用在聚合函数中使用的,功能其实都是对指定字段进行分组。
通过一下代码我们就得到了员工姓名ename,薪水sal,部门编号deptno和部门平均薪水AVG_sal
加下来我们只需要在这个结果中添加一个条件:员工薪水 > 部门平均薪水就能把问题解决了。
select ename,
sal,
deptno,
AVG(sal) over(partition by deptno) AVG_sal
from emp
添加条件:
select *
from t1
(select ename,
sal,
deptno,
AVG(sal) over(partition by deptno) AVG_sal
from emp)t1
where t1.sal > t1.AVG_sal;
这样写相比传统sql书写得到了简化,传统书写需要通过两个结果集进行关联,而通过聚合函数只需要在现有的结果集中进行条件筛选就ok了,同时也没有什么复杂的逻辑。
具体分析函数的学习可以移步b站:
在本例中用到的分析函数是AVG(),在传统的sql编写当中AVG()称之为聚合函数,在这里我们在AVG()函数后面用了关键字OVER,此时的AVG()就是分析函数了。
同样的,在其他聚合函数后面用上关键字over也会相应的成为分析函数。
这里的over是用于标识分析函数