SQL查询需求:筛选11月后薪资上涨及薪资变动的员工
嘿,我来帮你搞定这两个SQL查询问题!我会基于常见的业务表结构给出可行的方案,同时把逻辑讲清楚,方便你理解和调整:
问题1:获取11月后薪资有所上涨的员工信息
首先咱们假设存在一个月度薪资表 employee_salaries,结构如下:
employee_id:员工唯一ID(主键)employee_name:员工姓名salary_amount:当月薪资金额pay_month:支付月份,格式为YYYY-MM(比如'2018-11')
方案1:关联查询(查看所有11月后薪资上涨的记录)
这种方式会找出员工在11月之后任意月份薪资高于11月的所有记录,用DISTINCT可以避免同一个员工多条记录重复:
SELECT DISTINCT es.employee_id, es.employee_name, es.salary_amount AS current_salary, prev.salary_amount AS nov_salary FROM employee_salaries es JOIN ( -- 先获取所有员工2018年11月的薪资 SELECT employee_id, salary_amount FROM employee_salaries WHERE pay_month = '2018-11' ) prev ON es.employee_id = prev.employee_id -- 筛选11月之后的薪资记录,且金额高于11月 WHERE es.pay_month > '2018-11' AND es.salary_amount > prev.salary_amount;
方案2:窗口函数(精准找11月后第一个薪资上涨的月份)
如果只想看员工紧接11月之后第一个月薪资上涨的情况,用LAG窗口函数更高效:
SELECT employee_id, employee_name, pay_month, salary_amount, prev_salary FROM ( SELECT employee_id, employee_name, pay_month, salary_amount, -- 获取该员工上一个月的薪资 LAG(salary_amount) OVER (PARTITION BY employee_id ORDER BY pay_month) AS prev_salary, -- 获取上一个月的月份 LAG(pay_month) OVER (PARTITION BY employee_id ORDER BY pay_month) AS prev_month FROM employee_salaries ) sub -- 筛选上一个月是11月,且当前薪资更高的记录 WHERE prev_month = '2018-11' AND salary_amount > prev_salary;
问题2:提取2018年11月后薪资发生变动的员工ID
这里我猜你可能笔误了——你写的“2018年1月、2018年2月”应该是2019年1月、2月吧?毕竟11月之后的月份不可能是当年的1、2月。接下来基于这个修正后的需求来写方案:
咱们用给定的PMT表,结构是:
ID:员工唯一ID(主键)Pmt_Date:支付日期(格式比如'2018-11-15')Pmt_Amount:当月薪资金额
方案1:EXISTS子查询(简洁直观)
这种方式通过嵌套子查询检查员工是否存在11月后薪资和11月不同的情况:
SELECT DISTINCT p.id FROM PMT p -- 先限定范围在11月及之后的记录 WHERE DATE_FORMAT(p.Pmt_Date, '%Y-%m') >= '2018-11' AND EXISTS ( -- 找到该员工2018年11月的薪资 SELECT 1 FROM PMT p_nov WHERE p_nov.id = p.id AND DATE_FORMAT(p_nov.Pmt_Date, '%Y-%m') = '2018-11' AND EXISTS ( -- 检查该员工11月后是否有薪资不等于11月的记录 SELECT 1 FROM PMT p_later WHERE p_later.id = p.id AND DATE_FORMAT(p_later.Pmt_Date, '%Y-%m') IN ('2018-12', '2019-01', '2019-02') AND p_later.Pmt_Amount != p_nov.Pmt_Amount ) );
方案2:窗口函数+分组(高效聚合)
用窗口函数先获取每个员工11月的薪资,再筛选出之后月份薪资变动的记录,最后分组去重:
SELECT id FROM ( SELECT id, Pmt_Amount, DATE_FORMAT(Pmt_Date, '%Y-%m') AS pay_month, -- 获取该员工2018年11月的薪资 MAX(CASE WHEN pay_month = '2018-11' THEN Pmt_Amount END) OVER (PARTITION BY id) AS nov_salary FROM PMT -- 限定范围在目标月份内 WHERE DATE_FORMAT(Pmt_Date, '%Y-%m') IN ('2018-11', '2018-12', '2019-01', '2019-02') ) sub -- 筛选非11月的记录,且薪资不等于11月的 WHERE pay_month != '2018-11' AND Pmt_Amount != nov_salary GROUP BY id;
内容的提问来源于stack exchange,提问作者Abhishek Anand
相关产品推荐
相关产品推荐

