牛客 SQL:统计各个部门的工资记录数

该博客主要介绍如何使用MySQL查询每个部门的工资记录数量,帮助读者掌握数据库查询技巧。

题目:统计各个部门的工资记录数

代码:

SELECT dp.dept_no, dp.dept_name, T.MYSUM
FROM departments AS dp
INNER JOIN 
(
    SELECT de.dept_no, COUNT(*) AS MYSUM
    FROM dept_emp AS de
    INNER JOIN salaries AS s
    ON de.emp_no = s.emp_no
    GROUP BY de.dept_no
) AS T

ON dp.dept_no = T.dept_no
ORDER BY dp.dept_no ASC




<think> 我们正在统计活跃员工数量,参考了用户提供的引用内容,特别是引用[3]中关于活跃状态标签的定义(如30天内有订单视为活跃用户)。在员工活跃统计中,通常也是基于某个时间窗口内的活动记录。 根据用户之前的问题和引用内容,我们可以设计几个常见的统计场景: 1. **统计指定时间窗口内的活跃员工数量**(如最近30天) 2. **按时间维度(如天、月)分组统计活跃员工数量** 3. **统计连续活跃的员工(如连续30天活跃)** 由于引用[1]和[2]中提到了留存率和连续登录天数的统计,我们可以借鉴其中的方法。 假设我们有一个员工活动表`employee_activity`,包含以下字段: - `employee_id`:员工ID - `activity_date`:活动日期(假设为日期类型) 下面针对不同场景给出SQL示例: --- ### **场景1:统计最近30天活跃员工数量** ```sql SELECT COUNT(DISTINCT employee_id) AS active_employee_count FROM employee_activity WHERE activity_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY); ``` 这里我们统计了最近30天内有活动记录的员工数量(去重)。 --- ### **场景2:按天统计活跃员工数量** ```sql SELECT activity_date, COUNT(DISTINCT employee_id) AS daily_active_count FROM employee_activity GROUP BY activity_date ORDER BY activity_date; ``` 按天分组,统计每天活跃员工的数量。 --- ### **场景3:统计连续活跃30天的员工数量(参考引用[2]中的连续登录问题)** 连续活跃问题较为复杂,我们可以使用窗口函数来计算连续活跃天数,然后筛选连续天数>=30的员工。 步骤: 1. 对每个员工的活动记录按日期排序 2. 计算连续活跃的区间(通过日期差和行号差来判断) 3. 按员工分组,计算每个连续区间的天数 4. 筛选最大连续天数>=30的员工 具体SQL如下(以MySQL为例): ```sql WITH grouped_activity AS ( SELECT employee_id, activity_date, -- 计算当前行与前一行日期的差值(按员工分区按日期排序) DATE_SUB(activity_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY activity_date) DAY) AS grp FROM employee_activity GROUP BY employee_id, activity_date -- 同一天多次活动去重 ) SELECT employee_id, MAX(active_days) AS max_active_days FROM ( SELECT employee_id, grp, COUNT(*) AS active_days FROM grouped_activity GROUP BY employee_id, grp ) AS t GROUP BY employee_id HAVING max_active_days >= 30; ``` 这个查询会返回所有连续活跃天数至少达到30天的员工ID及其最大连续活跃天数。 注意:这里我们按员工和活动日期分组去重,避免同一天多次活动记录影响连续天数计算。 --- ### **注意事项** 1. **去重**:员工可能在一天内有多次活动记录,因此需要使用`DISTINCT`或`GROUP BY`去重。 2. **时间窗口**:活跃的定义需要明确时间窗口(如30天),这个窗口可以根据实际需求调整。 3. **连续活跃**:连续活跃统计较为复杂,需要借助窗口函数和分组技巧。 --- §§相关问题§§ 1. 如何定义员工的活跃状态(如活跃、高危、流失)? 2. 如何计算员工的留存率? 3. 如何用SQL统计员工在每周的活跃天数? </think> ### 笔试题:统计员工活跃数量解决方案 根据笔试真题和用户行为分析需求(参考引用[3]),以下是统计活跃员工数量的典型场景和SQL实现: --- #### **场景1:基础活跃统计(按时间窗口)** **题目要求**:统计最近30天活跃员工数量(活跃定义:有操作记录) **表结构**:`employee_activity(employee_id, activity_date)` ```sql SELECT COUNT(DISTINCT employee_id) AS active_count FROM employee_activity WHERE activity_date >= CURRENT_DATE - INTERVAL '30 days'; ``` **关键点**: - 时间窗口限定为最近30天(可根据需求调整) - `DISTINCT` 确保员工去重计数 - 适用于监控实时活跃度[^3] --- #### **场景2:分层活跃度统计(带状态标签)** **题目要求**:根据活跃频率标记员工状态(活跃/高危/流失) ```sql SELECT employee_id, CASE WHEN MAX(activity_date) >= CURRENT_DATE - 30 THEN '活跃' WHEN MAX(activity_date) BETWEEN CURRENT_DATE - 80 AND CURRENT_DATE - 31 THEN '高危' WHEN MAX(activity_date) < CURRENT_DATE - 80 THEN '流失' ELSE '注册未活跃' END AS status FROM employee_activity GROUP BY employee_id; ``` **状态定义参考**: - **活跃**:30天内有记录 - **高危**:31-80天内有记录 - **流失**:超过80天无记录[^3] --- #### **场景3:连续活跃统计(笔试高频题)** **题目要求**:找出连续7天活跃的员工(参考引用[2]连续登录逻辑) ```sql WITH daily_activity AS ( SELECT employee_id, activity_date, -- 计算连续活跃标记 activity_date - ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY activity_date) AS grp FROM ( SELECT DISTINCT employee_id, activity_date -- 去重 FROM employee_activity ) t ) SELECT employee_id FROM daily_activity GROUP BY employee_id, grp HAVING COUNT(*) >= 7; -- 连续7天活跃 ``` **核心技巧**: 1. 使用`ROW_NUMBER()`生成序号 2. 日期减序号得到连续活跃标记`grp` 3. 按`grp`分组后筛选满足天数的员工[^2] --- #### **场景4:月度活跃趋势分析** **题目要求**:按月输出活跃员工数量及环比变化 ```sql WITH monthly_active AS ( SELECT DATE_TRUNC('month', activity_date) AS month, COUNT(DISTINCT employee_id) AS active_count FROM employee_activity GROUP BY 1 ) SELECT month, active_count, ROUND( (active_count - LAG(active_count,1) OVER (ORDER BY month)) * 100.0 / LAG(active_count,1) OVER (ORDER BY month), 2 ) AS growth_rate FROM monthly_active; ``` **输出示例**: | month | active_count | growth_rate | |-----------|--------------|-------------| | 2023-09 | 1500 | null | | 2023-10 | 1820 | 21.33% | --- ### 注意事项 1. **时间区间处理**: - MySQL用`DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)` - PostgreSQL用`CURRENT_DATE - INTERVAL '30 days'` 2. **去重逻辑**:避免单日多次操作导致计数偏差 3. **空值处理**:使用`COALESCE(active_count,0)`避免NULL值 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值