人力资源报表 — 统计规则文档
一数据来源与范围
▼| 属性 | 内容 |
|---|---|
| 数据表 | staff_roster(MySQL nursing库) |
| 数据来源 | 轻流 openApi ahf2mv5g0g01 → sync_staff_roster.py 每日同步 |
| 数据量 | 2864条(在职 1587 + 离职 1277) |
核心规则:除离职相关统计外,所有统计均只计在职员工(
status='在职')。
报表通过 server.py 的 /api/hr-report/data API 接口提供数据,前端 hr-report.html 负责可视化展示。数据每日凌晨通过定时任务从轻流API全量同步到 staff_roster 表。
二Sheet1: 职级分布
▼
数据范围:仅在职员工,过滤
job_rank 为空的记录。
职级列
从 job_rank 字段直接取值,按以下固定顺序排列:
RANK_ORDER = ["高管", "总监", "院长", "副院长", "经理", "主任", "主管", "专员", "基层员工"]
行分组
按 institution 字段分组,各职级列为机构×职级的交叉人数。合计行为所有机构汇总。
三Sheet2: 性别分布
▼
数据范围:仅在职员工。
分组规则
从 gender 字段直接取值(男/女),在职总人数汇总统计。
占比 = 该性别人数 / 在职总人数 × 100%
四Sheet2: 学历分布
▼
数据范围:仅在职员工。
归组规则
从 education 字段归类:
| 显示类别 | 原始 education 值 |
|---|---|
| 硕士及以上 | education='硕士' |
| 本科 | education='本科' 或 '本科(自考)' |
| 大专 | education='大专' |
| 中专 | education='中专' |
| 高中 | education='高中' |
| 初中及以下 | education IN ('初中','小学','文盲') |
占比计算
占比 = 该学历人数 / 在职总人数 × 100%
注意:
education 字段可能存在空值或未归类的值(如"其他"、"博士"等),需在 SQL 中做兜底处理,将不匹配的值归入"其他"或排除。
五Sheet2: 年龄段分布
▼
数据范围:仅在职员工。
重要:年龄段从
age 数值字段重新计算,不使用 age_group 字段,因为区间不一致。
区间划分
| 显示类别 | SQL 条件 |
|---|---|
| 18-30 | age >= 18 AND age < 30 |
| 30-40 | age >= 30 AND age < 40 |
| 40-50 | age >= 40 AND age < 50 |
| 50-60 | age >= 50 AND age < 60 |
| 60+ | age >= 60 |
占比计算
占比 = 该年龄段人数 / 在职总人数 × 100%
六Sheet2: 司龄分布
▼
数据范围:仅在职员工。
从 tenure_years 字段直接取值(轻流滚动计算,同步时更新)。
分段规则
| 显示类别 | SQL 条件 |
|---|---|
| <6个月 | tenure_years < 0.5 |
| 0.5年-3年 | 0.5 ≤ tenure_years < 3 |
| 3年-5年 | 3 ≤ tenure_years < 5 |
| 5年-10年 | 5 ≤ tenure_years < 10 |
| 10年-20年 | 10 ≤ tenure_years < 20 |
| 20年及以上 | tenure_years ≥ 20 |
平均工龄
平均工龄 = AVG(tenure_years),排除空值
七Sheet3: 岗位序列分布
▼
数据范围:仅在职员工。
标准化映射
从 job_sequence 字段标准化,合并带/不带"序列"后缀的值:
| 显示类别 | 映射的原始值 |
|---|---|
| 管理 | 管理序列, 管理 |
| 护理 | 护理序列, 护理 |
| 医护 | 医护序列, 医护 |
| 行政 | 行政序列, 行政 |
| 后勤 | 后勤序列, 后勤 |
| 居家 | 居家序列, 居家 |
| 职能 | 职能序列 |
| 实习 | 实习序列 |
| 销售 | 销售序列 |
行分组
按 institution 字段分组。
标准化 SQL 示例
-- 使用 CASE WHEN 进行标准化映射
SELECT
institution,
CASE
WHEN job_sequence IN ('管理序列', '管理') THEN '管理'
WHEN job_sequence IN ('护理序列', '护理') THEN '护理'
WHEN job_sequence IN ('医护序列', '医护') THEN '医护'
WHEN job_sequence IN ('行政序列', '行政') THEN '行政'
WHEN job_sequence IN ('后勤序列', '后勤') THEN '后勤'
WHEN job_sequence IN ('居家序列', '居家') THEN '居家'
WHEN job_sequence = '职能序列' THEN '职能'
WHEN job_sequence = '实习序列' THEN '实习'
WHEN job_sequence = '销售序列' THEN '销售'
END AS seq_category
FROM staff_roster
WHERE status = '在职'
八Sheet3: 入离职统计
▼
数据范围:全量员工(在职 + 离职)。
各列取值规则
| 列名 | 取值逻辑 | 备注 |
|---|---|---|
| 期间入职 | entry_date 在用户选择的日期范围内 |
仅此列受日期范围影响 |
| 在职合计 | status='在职' 的人数 |
全体在职 |
| 累计主动离职 | status='离职' AND leave_type='主动离职' 的全部历史累计 |
全量累计 |
| 累计被动离职 | status='离职' AND leave_type='被动离职' 的全部历史累计 |
全量累计 |
| 累计总离职 | status='离职' 的全部历史累计 |
全量累计 |
| 试用期内离职 | status='离职' AND leave_date <= regular_date(离职日期在转正日期之前或当天) |
试用期内流出 |
重要:入离职统计不区分日期范围选择(日期范围仅影响"期间入职"列),离职数据为全量累计。即:累计主动离职、累计被动离职、累计总离职、试用期内离职这4列,始终返回机构自成立以来的全部历史数据。
九离职率计算公式
▼整体离职率
整体离职率 = 累计总离职人数 / (当前在职人数 + 累计总离职人数) × 100%
主动离职率
主动离职率 = 累计主动离职人数 / (当前在职人数 + 累计总离职人数) × 100%
关键理解:两个率的分母相同,均为 "在职 + 累计离职",代表该机构的员工总流动池。这个设计确保了离职率能够反映该机构自成立以来的总体人员流动水平。
计算示例
假设某机构当前在职 100人,累计主动离职 20人,累计被动离职 5人:
总流动池 = 100 + 20 + 5 = 125
整体离职率 = (20 + 5) / 125 × 100% = 20.0%
主动离职率 = 20 / 125 × 100% = 16.0%
十字段映射速查
▼| 报表指标 | DB字段 | 取值规则 |
|---|---|---|
| 职级 | job_rank | 直接取值,过滤空值 |
| 性别 | gender | 直接取值 |
| 学历归类 | education | 见Section 3归组规则 |
| 年龄段 | age | 数值区间计算,见Section 4 |
| 司龄分段 | tenure_years | 数值区间计算,见Section 5 |
| 岗位序列 | job_sequence | 标准化映射,见Section 6 |
| 入职日期 | entry_date | 日期范围匹配 |
| 在职状态 | status | status='在职' |
| 离职类型 | leave_type | 主动离职/被动离职/实习结束等 |
| 离职日期 | leave_date | 用于试用期判断 |
| 转正日期 | regular_date | 用于试用期判断 |
| 机构 | institution | 直接取值 |
各字段的详细取值逻辑请参阅对应的 Section(Section 3-6),包含完整的归组/分段/映射规则。