牛客SQL刷题

在牛客网刷数据库的题目 https://www.nowcoder.com/ta/sql


 1.查找最晚入职员工的所有信息(select) 

select * 
from employees 
order by hire_date desc
limit 1;

//最关键在于limit 1 ,表示总共只选择一个;(两个参数表示分页)
//desc降序

2.查找入职员工时间排名倒数第三的员工所有信息(select)

select * 
from employees 
order by hire_date desc 
limit 1 offset 2

//关键点在于offset
//limit 1 offset 2 ==>表示第3个
3.查找各个部门当前(dept_manager.to_date='9999-01-01')领导当前(salaries.to_date='9999-01-01')薪水详情以及其对应部门编号dept_no
(注:输出结果以salaries.emp_no升序排序) 
select s.emp_no,salary,from_date,s.to_date,dept_no
from salaries as s join dept_manager as d
where s.emp_no=d.emp_no and s.to_date='9999-01-01' and d.to_date='9999-01-01' //表示"当前"(本题特色)
order by s.emp_no

4.查找所有已经分配部门的员工的last_name和first_name以及dept_no(select)

select last_name,first_name,dept_no
from dept_emp as d left join employees as e
on d.emp_no=e.emp_no

//这里用left join或者inner join(join)都一样可以
//第一行里面,如果字段不是多表共有的,就可以不用指出是哪个表的属性(例e.last_name)

5.查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括暂时没有分配部门的员工(请注意输出描述里各个列的前后顺序)

select last_name,first_name,dept_no
from dept_emp as d right join employees as e
on d.emp_no=e.emp_no

//重点是:right join

6.查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序(select)

select e.emp_no,salary
from 
    employees as e left join salaries as s
    on e.emp_no=s.emp_no and e.hire_date=s.from_date
order by e.emp_no desc

//join后面紧接着on,并说明两表join的字段
//善用缩进,可以使结构清晰

7.查找薪水变动超过15次的员工号emp_no以及其对应的变动次数t (select,较难)

select emp_no,t from(
    select emp_no, count(salary) as t 
    from salaries
    group by emp_no
)alias_name
where t>15

//这个是典型的两次select查询,第一次select形成一张新的表(包括新的字段:count)用于给第二个select来查询
//select...from(...)alias_name where... 这是外层select,将alias_name表作为查询对象
//内层select先分组,再查询count信息

8.找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示

select distinct(salary) from salaries
where to_date='9999-01-01'
order by salary desc

//select后面直接跟distinct()来去重

9.获取所有部门当前(dept_manager.to_date='9999-01-01')manager的当前(salaries.to_date='9999-01-01')薪水情况,给出dept_no, emp_no以及salary,输出结果按照dept_no升序排列(请注意,同一个人可能有多条薪水情况记录)

select dept_no,d.emp_no,salary
from dept_manager as d join salaries as s on d.emp_no=s.emp_no
where d.to_date='9999-01-01' and s.to_date='9999-01-01'
order by dept_no

10.获取所有非manager的员工emp_no

select e.emp_no from employees as e
where e.emp_no not in (
    select d.emp_no from dept_manager as d
)

11.获取所有员工当前的(dept_manager.to_date='9999-01-01')manager,如果员工是manager的话不显示(也就是如果当前的manager是自己的话结果不显示)。输出结果第一列给出当前员工的emp_no,第二列给出其manager对应的emp_no。

select e.emp_no, m.emp_no as manager_no
from dept_emp as e join dept_manager as m 
    on e.dept_no = m.dept_no
where e.emp_no!=m.emp_no 
    and m.to_date='9999-01-01'
//这两个比较重要:
//where e.emp_no!=m.emp_no
//m.emp_no as manager_no

33.创建一个actor表(create table)

create table actor(
    actor_id smallint(5) not null primary key,
    first_name varchar(45) not null,
    last_name varchar(45) not null,
    last_update date not null
)
//主键直接在字段最后加上primary key就行

34.请你对于表actor批量插入如下数据(insert)

insert into actor
values
(1,'PENELOPE','GUINESS','2006-02-15 12:34:33'),
(2,'NICK','WAHLBERG','2006-02-15 12:34:33')

//varchar、date、time都要用单引号包起来(红字)
//第一行也可以写成insert into actor(actor_id,first_name,last_name,last_update),但是如果全部&有序,就可以省略表项字段

42.删除emp_no重复的记录,只保留最小的id对应的记录(delete,较难)

delete from titles_test
where id not in(
    select * from(
        select min(id) 
from titles_test group by emp_no )alias_name )

//delete from...where...固定套路
//not in 表示不在某范围
//select * from(...)alias_name 是嵌套一层别名(mysql-8.0不允许查找的同时删除,需要起别名)
//select的执行次序,在group by、having之后,所以可以先分组再从每个组里面分别select值

48.请你写出更新语句,将所有获取奖金的员工当前的(salaries.to_date='9999-01-01')薪水增加10%。(emp_bonus里面的emp_no都是当前获奖的所有员工)

(update)

方法1:连接查询(先join两张表)

update salaries as s join emp_bonus as e on s.emp_no=e.emp_no
set salary=salary*1.1
where to_date='9999-01-01'

//update...set...where... ==>固定套路
//set后面跟表达式

 方法2:子查询(两次select)

update salaries
set salary=salary*1.1
where to_date='9999-01-01' 
    and salaries.emp_no in(select emp_no from emp_bonus)

//这个in很关键,要区别于 "="

比较:
  推荐使用连接查询(JOIN)
  连接查询不需要创建+销毁临时表,因此速度比子查询快。

原文地址:https://www.cnblogs.com/qyf2199/p/14223719.html