SQL 变换结果集以实现跨行计算,你希望计算来自多行的数据。为了让这个任务变得容易些,你希望将那些行都转换为列,这样你需要的所有值都会出现在同一行里。
SQL 变换结果集以实现跨行计算 问题描述
你希望计算来自多行的数据。为了让这个任务变得容易些,你希望将那些行都转换为列,这样你需要的所有值都会出现在同一行里。
在本书的示例数据中,DEPTNO 20
是工资总额最高的部门,我们可以通过下列查询来确认一下数据。
select deptno, sum(sal) as sal
from emp
group by deptno
DEPTNO SAL
------ ----------
10 8750
20 10875
30 9400
你希望计算出上述 DEPTNO 20
和 DEPTNO 10
之间的工资总额的差值,以及上述 DEPTNO 20
和 DEPTNO 30
之间的工资总额差值。
SQL 变换结果集以实现跨行计算 解决问题
使用聚合函数 SUM
和 CASE
表达式计算工资总额,然后在 SELECT
列表里做差值计算。
1 select d20_sal - d10_sal as d20_10_diff,
2 d20_sal - d30_sal as d20_30_diff
3 from (
4 select sum(case when deptno=10 then sal end) as d10_sal,
5 sum(case when deptno=20 then sal end) as d20_sal,
6 sum(case when deptno=30 then sal end) as d30_sal
7 from emp
8 ) totals_by_dept
SQL 变换结果集以实现跨行计算 扩展知识
首先,使用 CASE
表达式把每个 DEPTNO
对应的工资从行形式变换为列形式。
select case when deptno=10 then sal end as d10_sal,
case when deptno=20 then sal end as d20_sal,
case when deptno=30 then sal end as d30_sal
from emp
D10_SAL D20_SAL D30_SAL
------- ---------- ----------
800
1600
1250
2975
1250
2850
2450
3000
5000
1500
1100
950
3000
1300
然后,在每一个 CASE
表达式里调用聚合函数 SUM
计算出每个 DEPTNO
对应的工资总额。
select sum(case when deptno=10 then sal end) as d10_sal,
sum(case when deptno=20 then sal end) as d20_sal,
sum(case when deptno=30 then sal end) as d30_sal
from emp
D10_SAL D20_SAL D30_SAL
------- ---------- ----------
8750 10875 9400
最后,只要把上述 SQL 查询放入到内嵌视图里,并在外层查询中执行减法运算即可。