SQL 计算比重

SQL 计算比重,报表中有一组数字值,你想同时显示每个值占总数的百分比。例如,你使用的是 Oracle 数据库,你希望返回一个按照 JOB 维度计算出来的工资分布情况,这样就能判断出哪些 JOB 耗费了公司最多的钱。你也希望把从事每种 JOB 的员工人数包括进来,以避免最终结果集中出现的百分比产生误导。

SQL 计算比重 问题描述

报表中有一组数字值,你想同时显示每个值占总数的百分比。例如,你使用的是 Oracle 数据库,你希望返回一个按照 JOB 维度计算出来的工资分布情况,这样就能判断出哪些 JOB 耗费了公司最多的钱。你也希望把从事每种 JOB 的员工人数包括进来,以避免最终结果集中出现的百分比产生误导。你希望得到如下所示的报表。

JOB         NUM_EMPS PCT_OF_ALL_SALARIES
--------- ---------- -------------------
CLERK              4                  14
ANALYST            2                  20
MANAGER            3                  28
SALESMAN           4                  19
PRESIDENT          1                  17

如上所述,如果报表中没有包含员工人数,看起来似乎总经理的工资比例并不高。加入员工人数后,我们才清楚地看到总经理一个人的工资竟然占了总数的 17%。

SQL 计算比重 解决方案

对于本问题而言,只有 Oracle 提供了一个合适的解决方案,因为 Oracle 支持内置函数 RATIO_TO_REPORT。对于其他数据库,为了计算比重,不妨使用除法,请参考 7.11 节。

1  select job,num_emps,sum(round(pct)) pct_of_all_salaries
2    from (
3  select job,
4         count(*)over(partition by job) num_emps,
5         ratio_to_report(sal)over()*100 pct
6    from emp
7          )
8   group by job,num_emps

SQL 计算比重 扩展知识

首先使用窗口函数 COUNT OVER 计算每个 JOB 对应的员工人数。然后使用 RATIO_TO_REPORT 计算每个员工的工资占总数的百分比(该值以小数形式返回)。

select job,
       count(*)over(partition by job) num_emps,
       ratio_to_report(sal)over()*100 pct
  from emp
 
JOB         NUM_EMPS        PCT
--------- ---------- ----------
ANALYST            2 10.3359173
ANALYST            2 10.3359173
CLERK              4 2.75624462
CLERK              4 3.78983635
CLERK              4  4.4788975
CLERK              4 3.27304048
MANAGER            3 10.2497847
MANAGER            3 8.44099914
MANAGER            3 9.81912145
PRESIDENT          1 17.2265289
SALESMAN           4 5.51248923
SALESMAN           4 4.30663221
SALESMAN           4 5.16795866
SALESMAN           4 4.30663221

最后,使用聚合函数 SUM 计算 RATIO_TO_REPORT 函数的返回值的合计值。不要忘记根据 JOBNUM_EMPS 分组。另外,要乘以 100 才能得到一个代表百分比的整数(例如,对于 25% 来说,应该返回的是 25 而不是 0.25):

select job,num_emps,sum(round(pct)) pct_of_all_salaries
  from (
select job,
       count(*)over(partition by job) num_emps,
       ratio_to_report(sal)over()*100 pct
  from emp
       )
 group by job,num_emps
 
JOB         NUM_EMPS PCT_OF_ALL_SALARIES
--------- ---------- -------------------
CLERK              4                  14
ANALYST            2                  20
MANAGER            3                  28
SALESMAN           4                  19
PRESIDENT          1                  17

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程