首页 > 试题广场 >

查找在职员工自入职以来的薪水涨幅情况

[编程题]查找在职员工自入职以来的薪水涨幅情况
  • 热度指数:557278 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
有一个员工表employees简况如下:
emp_no 
birth_date 
first_name 
last_name 
gender hire_date 
10001
1953-09-02
Georgi     
Facello   
 M 2001-06-22
10002
1964-06-02
Bezalel    
Simmel    
 F 1999-08-03

有一个薪水表salaries简况如下:
emp_no 
salary
from_date 
to_date
10001
85097 2001-06-22
2002-06-22
10001 88958
2002-06-22 9999-01-01
10002
72527 1999-08-03
2000-08-02
10002
72527 2000-08-02 2001-08-02

请你查找在职员工自入职以来的薪水涨幅情况(注意这里强调的是在职员工),给出在职员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序,以上例子输出为
(注: to_date为薪资调整某个结束日期,或者为离职日期,to_date='9999-01-01'时,表示依然在职,无后续调整记录)
emp_no growth
10001 3861
示例1

输入

drop table if exists  `employees` ; 
drop table if exists  `salaries` ;
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','2001-06-22');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1999-08-03');
INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1999-08-03','2000-08-02');
INSERT INTO salaries VALUES(10002,72527,'2000-08-02','2001-08-02');

输出

emp_no|growth
10001|3861
SELECT
    s1.emp_no AS emp_no,
    max( s2.salary - s1.salary ) AS growth 
FROM
    salaries AS s1
    LEFT JOIN salaries AS s2 ON s1.emp_no = s2.emp_no 
GROUP BY
    emp_no 
HAVING
    growth != 0;
那里出了问题啊,虽然时间复杂度是N²,但我看着没啥问题啊

发表于 2024-11-26 15:10:59 回复(0)
select emp_no
,max(salary)-min(salary) growth
from salaries
where emp_no in (
    select emp_no
    from salaries
    where to_date = '9999-01-01')
group by emp_no
order by growth;

这样为什么不对呢?
发表于 2024-11-24 19:10:57 回复(0)
select emp_no	
,sum(case when from_date=min_date  then -salary
      when to_date='9999-01-01'  then salary
     else 0  end
    ) growth
from
(select *
,min(from_date) over(partition by emp_no) min_date
from salaries) s 
where emp_no  in 
		(select emp_no from salaries where to_date='9999-01-01')
group by 1
order by 2

发表于 2024-11-14 18:49:28 回复(0)
感觉这个题有歧义吧,是算初始薪资和当前薪资的涨幅嘛,还是算每一次薪资变动的涨幅
发表于 2024-11-11 12:24:13 回复(0)
select
    t1.emp_no,
    t1.growth
from
    (
        select
            emp_no
        from
            salaries
        where
            to_date = '9999-01-01'
    ) t2 --在职员工的id
    left join (
        select
            emp_no,
            salary - last_salary as growth --当前薪资-上一次的薪资,此处可能为null,因为salaries中该员工可能只有一条数据
            # ifnull(salary - last_salary, 0) as growth 上述可以替换为该语句,把null变为0代表未出现工资变化
        from
            (
                select
                    emp_no,
                    salary,
                    lag (salary, 1, null) over (
                        partition by
                            emp_no  
                        order by
                            to_date  
                    ) as last_salary  --每个员工的上一次薪资变动的薪资
                from
                    salaries
            ) t
    ) t1 on t1.emp_no = t2.emp_no
where
    t1.growth is not null --growth为null的情况是根本没出现过工资变动的情况,salaries表中该员工只有一条数据

感觉这个才是比较符合题意的,薪资涨幅会出现负数,注意:此方法无法通过题解,这个方法是求出每次涨幅,不是求出最初与最终薪资差
可以通过的题解为
select
emp_no, cur_salary-orin_salary as growth
from
(select
emp_no, max(orin_salary) as orin_salary, max(cur_salary) as cur_salary
from
(select
e.emp_no,
if(e.hire_date=s.from_date, s.salary, null) as orin_salary,
if(s.to_date='9999-01-01',s.salary, null) as cur_salary
from employees e
join salaries s on e.emp_no=s.emp_no) t
group by emp_no)t2
where cur_salary-orin_salary is not null
order by cur_salary-orin_salary


发表于 2024-11-10 12:18:36 回复(0)

-- 先选出在职的人
-- 这个人的max-min
SELECT
    emp_no,
    MAX(salary) - MIN(salary) AS growth
FROM salaries
WHERE emp_no IN (
SELECT
    emp_no
FROM salaries
WHERE to_date = '9999-01-01'
)
GROUP BY emp_no
ORDER BY growth
这个为啥运行结果错误呀?感觉逻辑没问题呢
发表于 2024-10-31 18:04:29 回复(0)
select  b.emp_no,sum(b.growth) from
    (select  a.emp_no,
    (CASE WHEN a.r2 = 1 THEN a.salary ELSE 0 END) - 
    (CASE WHEN a.r1 = 1 THEN a.salary ELSE 0 END) AS growth
    from
        (select emp_no,salary,
        rank()over (partition by emp_no  order by  to_date ) r1,
        rank()over (partition by emp_no  order by to_date  desc) r2
        from  salaries
        where  emp_no IN(select emp_no  from   salaries where to_date='9999-01-01'))a
    WHERE 
    (a.r1 = 1 AND a.r2 = 2)or(a.r1 = 2 AND a.r2 = 1)) b
group by 1		

发表于 2024-10-24 19:59:05 回复(0)
#首先要确定在职员工是谁,然后要确定todate=9999时的工资,用salaries表where todate=9999即可
#然后得确定员工的入职时间,以及当时的工资,用employees表跟salaries表联结,找fromdate=hiredate即可
#然后用empno联结两表,后列/前列就得到了

select ss1.emp_no as emp_no,ss2.salary-ss1.salary as growth from salaries as ss1
inner join employees as e
on e.hire_date=ss1.from_date and ss1.emp_no=e.emp_no
inner join salaries as ss2
on ss2.to_date='9999-01-01' and ss2.emp_no=ss1.emp_no
order by growth;
发表于 2024-10-17 10:49:31 回复(0)
select
emp_no,
end_salary - start_salary growth
from (
select
emp_no,
to_date,
first_value(salary) over(partition by emp_no order by to_date desc) end_salary,
first_value(salary) over(partition by emp_no order by to_date) start_salary
from salaries a 
) a where to_date = '9999-01-01'
order by growth

发表于 2024-09-26 15:50:18 回复(0)
select
    s2.emp_no,
    max(maxsa - s2.salary) as growth
from
    salaries s2
    inner join (
        select
            s.emp_no,
            max(salary) as maxsa
        from
            salaries s
        where
            s.to_date = '9999-01-01'
        group by
            s.emp_no
    ) a on s2.emp_no = a.emp_no
group by
    s2.emp_no
order by
    growth
发表于 2024-09-13 11:32:33 回复(0)
select *
from (select a.emp_no, salary-lag(a.salary,1)over(partition by a.emp_no order by a.salary) growth
        from (select  salaries.emp_no, salaries.salary
              from salaries left join employees on salaries.emp_no = employees.emp_no
              where hire_date = from_date&nbs***bsp;to_date = '9999-01-01') a
        where a.emp_no in (select emp_no
                            from salaries
                            where to_date = '9999-01-01') ) b
where b.growth >= 0
order by growth asc

终于用偏移窗口写出来了,一开始没写对,虽然有点麻烦,不知道还有没有可以改进的。
发表于 2024-09-03 15:10:57 回复(0)
with t1 as (
    select *,
    lead(salary) over(partition by emp_no order by to_date) as salary_lead,
    lag(salary) over(partition by emp_no order by to_date) as salary_lag
    from salaries
), # 求薪资的上下值
t2 as (
    select t1.emp_no,
        sum(case when salary_lag is null then salary else 0 end) as min_salary,
        sum(case when salary_lead is null then salary else 0 end) as max_salary
    from t1 group by t1.emp_no
) # 求每个员工的最低工资和最高工资
select t2.emp_no,(t2.max_salary-t2.min_salary) as growth 
from t2 where t2.emp_no in 
(select emp_no from salaries where to_date='9999-01-01') 
order by growth # 去除离职人员

发表于 2024-08-14 15:22:55 回复(1)
SELECT a.emp_no,( a.salary - b.salary ) AS growth 
FROM
    ( SELECT emp_no, MAX( salary ) AS salary FROM salaries WHERE to_date = '9999-01-01' GROUP BY emp_no ) AS a
    JOIN ( SELECT emp_no, min( salary ) AS salary FROM salaries GROUP BY emp_no ) AS b ON a.emp_no = b.emp_no 
ORDER BY
    growth ASC
;
发表于 2024-08-14 00:35:30 回复(0)
大佬帮我看看

select a1.emp_no,a2.salary - a1.salary as growth from
(select
    *
from
    (
        select
            emp_no,
            salary,
            row_number() over (
                partition by
                    emp_no
                order by
                    to_date
            ) as pm
        from
            salaries
    ) as A
where pm = 1) as a1,
(select
    *
from
    (
        select
            emp_no,
            salary,
            row_number() over (
                partition by
                    emp_no
                order by
                    to_date
            ) as pm
        from
            salaries
    ) as A
where
    pm = 2) as a2 where a2.salary - a1.salary and a2.salary <> a1.salary
and a1.emp_no = a2.emp_no
发表于 2024-08-13 20:18:04 回复(0)
select emp_no
,(new_salary-salary) growth
from
(
select a.emp_no
,a.salary
,lead(a.salary) over() as new_salary
,row_number() over(partition by a.emp_no) rnk1
from salaries a
join
(
select emp_no
,min(from_date) min_date
,max(to_date) max_date
from salaries 
group by emp_no
having max_date ='9999-01-01'
) b
where a.emp_no=b.emp_no
and a.from_date<=b.min_date&nbs***bsp;a.to_date>=b.max_date
order by to_date desc
) new
where rnk1=1
order by growth 

发表于 2024-08-13 11:19:20 回复(0)
select
    emp_no,
    growth
from
    (
        select
            *,
            last_value (salary) over (
                partition by
                    emp_no
                order by
                    from_date asc rows between unbounded preceding
                    and unbounded following
            ) - first_value (salary) over (
                partition by
                    emp_no
                order by
                    from_date asc
            ) as growth
        from
            (
                select
                    *,
                    last_value (to_date) over (
                        partition by
                            emp_no
                        order by
                            to_date asc rows between unbounded preceding
                            and unbounded following
                    ) b
                from
                    salaries
            ) a
    ) a
where
    a.b = '9999-01-01'
    and a.to_date = '9999-01-01'
order by
    growth

发表于 2024-08-10 22:24:21 回复(0)
为什么有一条数据错了,看不到完整数据,是不是bug了
with
t0 as(select s.* from
(select emp_no
from salaries
where to_date='9999-01-01') a inner join salaries s on a.emp_no=s.emp_no),
t1 as (select emp_no,max(salary) mx
from t0
group by emp_no),
t2 as(select emp_no,min(salary)mn
from t0
group by emp_no)
select t1.emp_no,(mx-mn)
from t1 left join t2 on t1.emp_no=t2.emp_no
order by (mx-mn);

发表于 2024-08-05 19:41:47 回复(0)
SELECT emp_no,((SELECT MAX(salary)
                FROM salaries s3
                JOIN employees e3 USING(emp_no)
                WHERE s1.emp_no=s3.emp_no AND
                to_date='9999-01-01')
                -(SELECT salary
                    FROM salaries s2
                    JOIN employees e2 USING(emp_no)
                    WHERE s1.emp_no=s2.emp_no AND
                    from_date=hire_date)) AS growth
FROM salaries s1
JOIN employees e1 USING(emp_no)
WHERE to_date='9999-01-01'
ORDER BY growth


发表于 2024-07-27 11:25:57 回复(0)