牛客SQL编程SQL57-SQL64

SQL57.使用含有关键字exists查找未分配具体部门的员工的所有信息。
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 dept_emp (
emp_no int(11) NOT NULL,
dept_no char(4) NOT NULL,
from_date date NOT NULL,
to_date date NOT NULL,
PRIMARY KEY (emp_no,dept_no));
解题思路:没有分配部门的员工不存在于dept_emp表中,找出不存在于dept_emp表的员工的记录

select * from employees
where not exists (select emp_no from dept_emp
                 where employees.emp_no=dept_emp.emp_no);

SQL59.获取有奖金的员工相关信息,给出emp_no、first_name、last_name、奖金类型btype、对应的当前薪水情况salary以及奖金金额bonus。 bonus类型btype为1其奖金为薪水salary的10%,btype为2其奖金为薪水的20%,其他类型均为薪水的30%。 当前薪水表示to_date=‘9999-01-01’
解题思路:其他的只需要连接表即可,bonus可以使用case语句进行分类

select e.emp_no,e.first_name,e.last_name,b.btype,s.salary,
case when b.btype=1 then s.salary*0.1
when b.btype=2 then s.salary*0.2
when b.btype=3 then s.salary*0.3
end bonus
from employees as e,emp_bonus as b,salaries as s
where e.emp_no=b.emp_no
and e.emp_no=s.emp_no
and s.to_date="9999-01-01";

SQL60.按照salary的累计和running_total,其中running_total为前N个当前( to_date = ‘9999-01-01’)员工的salary累计和,其他以此类推。 具体结果如下Demo展示。。
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));
解题思路:把sum聚合函数作为窗口函数使用,所有聚合函数都能用做窗口函数,其语法和专用窗口函数完全相同。
sum(<汇总列>) over(<排序列>) as 别名;

select emp_no,salary,sum(salary) over(order by emp_no) as running_total
from salaries
where to_date="9999-01-01";

SQL61.对于employees表中,输出first_name排名(按first_name升序排序)为奇数的first_name,且输出时不需排序
解题思路:使用窗口函数,题目要求输出不排序,所以在子查询中查出first_name的排名,再连接employees表输出结果

select e.first_name
from employees as e join
    (select first_name,
     row_number() over(order by first_name) as r_rank
     from employees
    )as a
on e.first_name=a.first_name
where a.r_rank%2=1;

还可以使用count函数,小于等于e1的first_name的只有它本身和前面的first_name,记录数量加起来等于他自己的排名

elect e1.first_name
from employees as e1
where (select count(*) from employees as e2 
      where e1.first_name>=e2.first_name)%2=1

SQL62.在牛客刷题的小伙伴们都有着牛客积分,积分(grade)表简化可以如下:id为用户主键id,number代表积分情况,让你写一个sql查询,积分表里面出现三次以及三次以上的积分
解题思路:使用group by子句分组,在使用having子句筛选结果

select number
from grade
group by number
having count(number)>=3;

SQL63.在牛客刷题有一个通过题目个数的(passing_number)表,id是主键,请你根据上表,输出通过的题目的排名,通过题目个数相同的,排名相同,此时按照id升序排列
解题思路:使用窗口函数,按number逆序排序得出排名
排序详解
情况:第一条和第二条记录相同,第三条和第四条记录相同
rank函数:在排序时,如果存在相同位次的记录,会跳过之后的位次,比如1,1,3,3…
dense_rank函数:在排序时,如果存在相同位次的记录,却不会跳过之后的位次,比如1,1,2,2…
row_number函数:赋予唯一的连续位次,比如1,2,3,4…

select id,number,dense_rank() over(order by number desc) as t_rank
from passing_number
order by t_rank,id;

SQL64.请你找到每个人的任务情况,并且输出出来,没有任务的也要输出,而且输出结果按照person的id升序排序
解题思路:使用左连接,并按照person的id升序排序。

select p.id,p.name,t.content
from person as p left join task as t
on p.id=t.person_id
order by p.id
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值