【MySQL】临时变量使用之职员招聘人数(额外小知识点:SQL查询为空设置默认值)

文章讲述了如何使用SQL查询来根据公司的招聘预算和优先级(雇佣最多高级员工,然后用剩余预算雇佣初级员工)来确定接受的高级和初级员工数量。作者给出了一个示例以及自己的代码实现,强调了如何处理查询为空和设置默认值的情况。
摘要由CSDN通过智能技术生成

力扣题

1、题目地址

2004. 职员招聘人数

2、模拟表

表:Candidates

Column NameType
employee_idint
experienceenum
salaryint
  • employee_id是此表的主键列。
  • 经验是包含一个值(“高级”、“初级”)的枚举类型。
  • 此表的每一行都显示候选人的id、月薪和经验。

3、要求

一家公司想雇佣新员工。公司的工资预算是 70000 美元。公司的招聘标准是:

  1. 雇佣最多的高级员工。
  2. 在雇佣最多的高级员工后,使用剩余预算雇佣最多的初级员工。

编写一个SQL查询,查找根据上述标准雇佣的高级员工和初级员工的数量。

按 任意顺序 返回结果表。

4、示例

示例一

输入:

Candidates 表:

employee_idexperiencesalary
1Junior10000
9Junior10000
2Senior20000
11Senior20000
13Senior50000
4Junior40000

输出:

experienceaccepted_candidates
Senior2
Junior2

说明:

我们可以雇佣2名ID为(2,11)的高级员工。
由于预算是7万美元,他们的工资总额是4万美元,我们还有3万美元,但他们不足以雇佣ID为13的高级员工。

我们可以雇佣2名ID为(1,9)的初级员工。
由于剩下的预算是3万美元,他们的工资总额是2万美元,我们还有1万美元,但他们不足以雇佣ID为4的初级员工。

示例二

输入:
Candidates 表:

employee_idexperiencesalary
1Junior10000
9Junior10000
2Senior80000
11Senior80000
13Senior80000
4Junior40000

输出:

experienceaccepted_candidates
Senior0
Junior3

解释:

我们不能用目前的预算雇佣任何高级员工,因为我们需要至少80000美元来雇佣一名高级员工。
我们可以用剩下的预算雇佣三名初级员工。

5、代码编写

我的代码

# 查询高级员工且按工资正序,加序号是为了进行累加计算
with tmp as (
    select *, row_number() over (order by salary) AS rn
    from Candidates
    where experience = 'Senior'
), 
# 根据序号进行工资累加计算,取到小于等于70000即可,然后算出剩余的钱
tmp2 as (
    select 70000-sum(b.salary) AS money
    from tmp a, tmp b 
    where a.rn >= b.rn
    group by a.rn
    having sum(b.salary) <= 70000
    order by a.rn desc
    limit 1
), 
# 因为可能存在雇不起高级员工的情况,查询为空,就需要设置默认值70000(工资预算)
tmp3 as (
    select money from tmp2
    union all
    select 70000
    where not exists(select money from tmp2)
), 
#  查询初级员工且按工资正序,加序号是为了进行累加计算
tmp4 as (
    select *, row_number() over (order by salary) AS rn
    from Candidates
    where experience = 'Junior'
), 
# 根据序号进行工资累加计算,取到小于等于70000即可,利用序号倒序取出所雇人数
tmp5 as (
    select 'Senior' AS experience, count(*) AS accepted_candidates
    from tmp a, tmp b 
    where a.rn >= b.rn
    group by a.rn
    having sum(b.salary) <= 70000
    order by a.rn desc
    limit 1
), 
# 因为可能出现查询为空的情况,所以需要设置默认值'Senior', 0(高级员工默认招人数)
tmp6 as (
    select * from tmp5
    union all
    select 'Senior', 0
    where not exists(select * from tmp5)
), 
# 根据序号进行工资累加计算,取到小于等于雇高级员工后剩余的钱即可,利用序号倒序取出所雇人数
tmp7 as (
    select 'Junior' AS experience, count(*) AS accepted_candidates
    from tmp4 a, tmp4 b
    where a.rn >= b.rn
    group by a.rn
    having sum(b.salary) <= (select money from tmp3)
    order by a.rn desc
    limit 1
),
# 因为可能出现查询为空的情况,所以需要设置默认值'Junior', 0(初级员工默认招人数)
tmp8 as (
    select * from tmp7
    union all
    select 'Junior', 0
    where not exists(select * from tmp7)
)
select * from tmp6
union all
select * from tmp8

网友代码(临时变量写法)

with temp as(
    select experience,
           salary,
           (case when @tmp>=salary then 1 else 0 end) x,
           @tmp:=if(@tmp>=salary, @tmp-salary, @tmp) y
    from (
        select *, 
               @tmp:=70000
        from Candidates
    ) z
    order by experience, salary
)

select experience,
       sum(x) accepted_candidates 
from temp
group by experience

里面有个点很奇怪,英文顺序 J K L M N O P Q R S,J明明在S前面,用倒序S竟然会出现在J后面(这个暂时不理解)

select *
from Candidates
order by experience desc, salary

期望结果

| employee_id | experience | salary |
| ----------- | ---------- | ------ |
| 2           | Senior     | 20000  |
| 11          | Senior     | 20000  |
| 13          | Senior     | 50000  |
| 1           | Junior     | 10000  |
| 9           | Junior     | 10000  |
| 4           | Junior     | 40000  |

实际结果

| employee_id | experience | salary |
| ----------- | ---------- | ------ |
| 1           | Junior     | 10000  |
| 9           | Junior     | 10000  |
| 4           | Junior     | 40000  |
| 2           | Senior     | 20000  |
| 11          | Senior     | 20000  |
| 13          | Senior     | 50000  |

知识点

SQL查询为空设置默认值

在前面我的写法里面,两个地方用到了设置默认值

select money from tmp2
union all
select 70000
where not exists(select money from tmp2)
select * from tmp5
union all
select 'Senior', 0
where not exists(select * from tmp5)

会发现两个关键点
1、union all 前面的部分会在 union all 后面 not exists 里面出现
2、union all 后面的语句是没有连表的(这个是绝对不能连表的,测试过了)
其中 select 70000select 'Senior', 0 就是设置默认值

临时变量

用法可参考我之前写的文章:【MySQL】临时变量用法

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值