zoukankan      html  css  js  c++  java
  • 牛客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)
      连接查询不需要创建+销毁临时表,因此速度比子查询快。

  • 相关阅读:
    iOS 友盟统计
    iOS 高德地图 根据经纬度解析成位置
    十六、Swift 可选值链条 Optional Chaining
    十五、自动引用计数 Automatic Reference Counting
    十四、析构器 Deinitialization
    BCB应对WIN7的放大屏幕文本技术
    十三、初始化 Initialization
    十二、继承 Inheritance
    十一、下标 Subscripts
    十、方法 Methods
  • 原文地址:https://www.cnblogs.com/qyf2199/p/14223719.html
Copyright © 2011-2022 走看看