美文网首页数据分析oracle的基本sql介绍数据库
Oracle统计每个公司每年的员工信息——另类“两次分组”

Oracle统计每个公司每年的员工信息——另类“两次分组”

作者: 新手村的0级玩家 | 来源:发表于2018-04-23 11:02 被阅读17次

1.前言

昨天遇到一个统计的问题,数据大概14w条左右,在Excel文件中,原本打算用之前学的python练练手,后来时间紧,就直接导到Oracle数据库里统计了,解决的过程挺有意思,特此记录如下:

2.需求

现有3000多家公司2008年-2016年 员工的信息;约有14w条数据;存储在 Excel文件中;

为保护隐私此处数据为模拟数据

要求统计:
1.每个公司每年的员工数
2.每个公司每年的男、女员工数
3.每个公司每年的员工的平均年龄

sql语句在最后,如急需可跳至末尾
sql语句在最后,如急需可跳至末尾
sql语句在最后,如急需可跳至末尾

3.前导知识

3.1 case 一般语句

  • case 语句带有选择效果知返回第一个条件满足要求的语句,即语句一语句二都的判断都为 true ,返回排在前面的。
  • case 的语法根据放置的位置不同而不同。
CASE    SELECTOR
    WHEN   EXPRESSION_1 THEN STATEMENT_1;
    [WHEN EXPRESSION_2 THEN STATEMENT_2;]
    [...]
    [ELSE STATEMENT_N+1 ;]
END CASE;
  • 注意 在then 后面需要 ; 分号,而且结束的时候 是 END CASE ;
CASE v_element
    WHEN  xx  THEN yy;
    WHEN  xxx THEN  yyy;
    ELSE  yyyy;
END CASE;

当v_element 等于 xx 时,执行 yy 语句,如果很长可以 前后加 begin 和 end,判断的条件是 v_element =xx ,xx是 具体值。

3.2搜索式 case 语句

CASE 
    WHEN SEARCH_CONDITION_1 THEN STATEMENT_1;
    [WHEN SEARCH_CONDITION_1 THEN STATEMENT_2;]
    [...]
    [ELSE STATEMENT_N+1 ;]
END CASE;
CASE 
    WHEN  v_element=xx  THEN yy;
    WHEN  v_element=xxx THEN  yyy;
    ELSE  yyyy;
END CASE;

4.问题分析

问题解决的难点在于:每个公司每年的

4.1正常“两次分组”

比较直观的解决办法是:先按照公司分组,再按照分组 同时添加约束条件即可统计

统计出来的数据结果是这样的:

4.2“曲线两次分组”

如果要求一个公司的信息统计为一条数据

此时只能首先按照公司分组,分组之后,组内再利用case 语句“曲线实现分组”的效果

5.问题解决

5.1环境介绍

1.Oracle 11g 64位
2.PLSQL 11.0.3.1700
3.Microsoft Office 2013

5.2建表

create table gsygxx
(
  gsdm VARCHAR2(16),
  tjsj VARCHAR2(64),
  xm   VARCHAR2(32),
  xb   VARCHAR2(8),
  nl   NUMBER
)

5.3Excel数据导入

5.4正常“两次分组”源代码

先按照公司分组,再按照分组 得到的数据是每个公司每年的员工信息
直接添加约束条件,即可统计出结果

select 
gsdm 公司代码,
tjsj 统计时间,

count(*) 总人数,
avg  (nl) 平均年龄,

count(CASE WHEN xb='女' THEN 1    ELSE NULL   END) 女,
count(CASE WHEN xb='男' THEN 1    ELSE NULL   END) 男

from gsygxx
group by gsdm,tjsj
order by gsdm,tjsj;

5.5“曲线两次分组”源代码

1.按照公司分组 得到的是每个公司的全部年份的全部员工信息:在添加约束条件时,需要额外的添加上年份的限制
2.为了满足一个公司的信息统计为一条数据,需要把不同年份的数据分别在一条sql语句中进行统计

select 
gsdm 公司代码,
count(*) 总人数,

avg   (CASE WHEN tjsj = '2008-12-31' THEN  nl  ELSE NULL   END) 平均年龄_2008,
count (CASE WHEN tjsj = '2008-12-31' THEN 1    ELSE NULL   END) 总人数_2008,
count (CASE WHEN tjsj = '2008-12-31' and xb='男' THEN 1    ELSE NULL   END) 总人数_2008_男,
count (CASE WHEN tjsj = '2008-12-31' and xb='女' THEN 1    ELSE NULL   END) 总人数_2008_女,

avg   (CASE WHEN tjsj = '2009-12-31' THEN  nl  ELSE NULL   END) 平均年龄_2009,
count (CASE WHEN tjsj = '2009-12-31' THEN 1    ELSE NULL   END) 总人数_2009,
count (CASE WHEN tjsj = '2009-12-31' and xb='男' THEN 1    ELSE NULL   END) 总人数_2009_男,
count (CASE WHEN tjsj = '2009-12-31' and xb='女' THEN 1    ELSE NULL   END) 总人数_2009_女,


avg   (CASE WHEN tjsj = '2010-12-31' THEN  nl  ELSE NULL   END) 平均年龄_2010,
count (CASE WHEN tjsj = '2010-12-31' THEN 1    ELSE NULL   END) 总人数_2010,
count (CASE WHEN tjsj = '2010-12-31' and xb='男' THEN 1    ELSE NULL   END) 总人数_2010_男,
count (CASE WHEN tjsj = '2010-12-31' and xb='女' THEN 1    ELSE NULL   END) 总人数_2010_女,

avg   (CASE WHEN tjsj = '2011-12-31' THEN  nl  ELSE NULL   END) 平均年龄_2011,
count (CASE WHEN tjsj = '2011-12-31' THEN 1    ELSE NULL   END) 总人数_2011,
count (CASE WHEN tjsj = '2011-12-31' and xb='男' THEN 1    ELSE NULL   END) 总人数_2011_男,
count (CASE WHEN tjsj = '2011-12-31' and xb='女' THEN 1    ELSE NULL   END) 总人数_2011_女,

avg   (CASE WHEN tjsj = '2012-12-31' THEN  nl  ELSE NULL   END) 平均年龄_2012,
count (CASE WHEN tjsj = '2012-12-31' THEN 1    ELSE NULL   END) 总人数_2012,
count (CASE WHEN tjsj = '2012-12-31' and xb='男' THEN 1    ELSE NULL   END) 总人数_2012_男,
count (CASE WHEN tjsj = '2012-12-31' and xb='女' THEN 1    ELSE NULL   END) 总人数_2012_女,

avg   (CASE WHEN tjsj = '2013-12-31' THEN  nl  ELSE NULL   END) 平均年龄_2013,
count (CASE WHEN tjsj = '2013-12-31' THEN 1    ELSE NULL   END) 总人数_2013,
count (CASE WHEN tjsj = '2013-12-31' and xb='男' THEN 1    ELSE NULL   END) 总人数_2013_男,
count (CASE WHEN tjsj = '2013-12-31' and xb='女' THEN 1    ELSE NULL   END) 总人数_2013_女,

avg   (CASE WHEN tjsj = '2014-12-31' THEN  nl  ELSE NULL   END) 平均年龄_2014,
count (CASE WHEN tjsj = '2014-12-31' THEN 1    ELSE NULL   END) 总人数_2014,
count (CASE WHEN tjsj = '2014-12-31' and xb='男' THEN 1    ELSE NULL   END) 总人数_2014_男,
count (CASE WHEN tjsj = '2014-12-31' and xb='女' THEN 1    ELSE NULL   END) 总人数_2014_女,

avg   (CASE WHEN tjsj = '2015-12-31' THEN  nl  ELSE NULL   END) 平均年龄_2015,
count (CASE WHEN tjsj = '2015-12-31' THEN 1    ELSE NULL   END) 总人数_2015,
count (CASE WHEN tjsj = '2015-12-31' and xb='男' THEN 1    ELSE NULL   END) 总人数_2015_男,
count (CASE WHEN tjsj = '2015-12-31' and xb='女' THEN 1    ELSE NULL   END) 总人数_2015_女,

avg   (CASE WHEN tjsj = '2016-12-31' THEN  nl  ELSE NULL   END) 平均年龄_2016,
count (CASE WHEN tjsj = '2016-12-31' THEN 1    ELSE NULL   END) 总人数_2016,
count (CASE WHEN tjsj = '2016-12-31' and xb='男' THEN 1    ELSE NULL   END) 总人数_2016_男,
count (CASE WHEN tjsj = '2016-12-31' and xb='女' THEN 1    ELSE NULL   END) 总人数_2016_女


from gsygxx
group by gsdm 
order by gsdm;

5.5拓展

根据上面的分析和源代码,我们不难对其进行稍稍拓展,可以统计

1.每个公司每年男员工在某个年龄段(如 30-40岁)的数量

2.每个公司每年的男、女员工的平均年龄

3.每个公司每年的男、女员工数的比例

4.每个公司每年员工增加的个数(第一年不统计)

相关文章

  • Oracle统计每个公司每年的员工信息——另类“两次分组”

    1.前言 昨天遇到一个统计的问题,数据大概14w条左右,在Excel文件中,原本打算用之前学的python练练手,...

  • 2020-04-10-(2)

    分组比较 Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department...

  • django分组统计

    1、统计每个月的订单总数 2、统计每年的订单总数 3、统计每件商品卖出去的订单总额(分组显示) 4、统计所有订单的...

  • oracle统计信息

    查看自动收集统计信息的任务及状态sys@ora11g> select client_name,status fro...

  • Oracle 统计信息

    Oracle统计信息是存储在数据字典里的一组数据,从多个维度描述了oracle数据库里对象的详细信息。CBO会利用...

  • oracle统计信息

    统计级别 show parameter statistics_level basic :自动优化功能会禁用 typ...

  • 封城当天通知延迟上班

    今天公司统计信息,员工的身体状况、地址、有无在家办公等信息。 比起群里面别人讨论公司如何欺诈员工,让员工按时回去上...

  • Oracle分组函数之ROLLUP用法

    rollup函数本博客简单介绍一下oracle分组函数之rollup的用法,rollup函数常用于分组统计,也是属...

  • 比年终奖更具诱惑力 中环绿源帮你留住员工的心

    临近春节,每个公司的员工都有自己的小心思,都在谋划着年后的工作去向。据统计每年一至三月份是员工离职率最高的时期,很...

  • 窗口函数sum应用于累计求和

    需求 方案1分组统计每个月消费金额,然后自连接,再分组聚合 方案2分组统计,窗口聚合函数

网友评论

    本文标题:Oracle统计每个公司每年的员工信息——另类“两次分组”

    本文链接:https://www.haomeiwen.com/subject/pylklftx.html