牛客网sql练习题解(12-21)

文章目录

    • 简介
    • NO.12
    • NO.13
    • NO.14
    • NO.15
    • NO.16
    • NO.17
    • NO.18
    • NO.19
    • NO.20
    • NO.21

简介

按时来更,感觉题目不是很难,不过我有一个感觉就是虽然题目简单不过如果你只是靠上课知道的那些东西而不亲自动手的话会出现眼高手低的问题。总之,如果大家有兴趣不妨看看,haha。

下面的目录是对应的题号

往期文章:
牛客网sql练习题解 (1-11)
牛客网sql练习题解(12-21)
牛客网sql练习题解(22-32)
牛客网sql练习题解(34-42)

NO.12

牛客网sql练习题解(12-21)_第1张图片

select de.dept_no, de.emp_no, max(s.salary) as salary
from dept_emp de left join salaries s
on de.emp_no = s.emp_no
where de.to_date = '9999-01-01'
group by de.dept_no;

牛客网sql练习题解(12-21)_第2张图片
当然还有一种写法

select de.dept_no, de.emp_no, s.salary
from dept_emp de left join salaries s
on de.emp_no = s.emp_no
where de.to_date = '9999-01-01'
group by de.dept_no
having max(s.salary);

牛客网sql练习题解(12-21)_第3张图片

NO.13

牛客网sql练习题解(12-21)_第4张图片

select title, count(*) as t
from titles
group by title
having count()>=2;

牛客网sql练习题解(12-21)_第5张图片

NO.14

牛客网sql练习题解(12-21)_第6张图片

select title, count(distinct emp_no) as t
from titles
group by title
having count(distinct emp_no) >= 2

牛客网sql练习题解(12-21)_第7张图片

NO.15

牛客网sql练习题解(12-21)_第8张图片

select *
from employees
where emp_no % 2 = 1 and last_name <> 'Mary'
order by hire_date desc;

补充:emp_no % 2=1也可以改成MOD(emp_no, 2)=1,但是某些sql版本可能不支持后者(比如题库就不支持)
补充:不相等有三种表示方式:<>、!=、IS NOT
注意:last_name是varchar类型,所以对它的判断需要加上单引号

牛客网sql练习题解(12-21)_第9张图片
或者:
用&号

select *
from employees
where emp_no&1 and last_name <> 'Mary'
order by hire_date desc;

牛客网sql练习题解(12-21)_第10张图片

NO.16

牛客网sql练习题解(12-21)_第11张图片

select t.title, avg(s.salary) as avg
from salaries s left join titles t
on s.emp_no = t.emp_no
where t.to_date = '9999-01-01' and s.to_date = '9999-01-01'
group by t.title;

牛客网sql练习题解(12-21)_第12张图片
或者使用子查询,然后两步走:

SELECT title, avg(salary)
FROM (
SELECT t.title as title, t.emp_no as emp_no, s.salary as salary
FROM titles AS t, salaries AS s
WHERE t.emp_no=s.emp_no
AND s.to_date='9999-01-01'
AND t.to_date='9999-01-01'
)
GROUP BY title

牛客网sql练习题解(12-21)_第13张图片

NO.17

牛客网sql练习题解(12-21)_第14张图片

-- topN
select emp_no, salary
from salaries
where salary = (
    select distinct s.salary
    from salaries s
    where s.to_date = '9999-01-01'
    order by s.salary desc
    limit 1 offset 1
);

牛客网sql练习题解(12-21)_第15张图片
这里我是用的是子查询+distinct
还可以用子查询+group by的方法

NO.18

牛客网sql练习题解(12-21)_第16张图片

不使用order by的topN问题

select e.emp_no, s.salary, e.last_name, e.first_name
from  salaries s, employees e
where s.emp_no = e.emp_no and s.to_date = '9999-01-01'
and s.salary = (
    select max(salary)
    from salaries
    where to_date = '9999-01-01'
    and salary < (
        select max(salary)
        from salaries s2
        where to_date = '9999-01-01'
    )
);

牛客网sql练习题解(12-21)_第17张图片

第二种方法

select s.emp_no, s.salary, e.last_name, e.first_name
from salaries s join employees e on s.emp_no = e.emp_no
where s.to_date = '9999-01-01'
and s.salary = (
    select s1.salary
    from salaries s1 join salaries s2
    on s1.salary <= s2.salary
    group by s1.salary
    having count(distinct s2.salary) = 2 
    and s1.to_date = '9999-01-01' 
    and s2.to_date = '9999-01-01'
);

牛客网sql练习题解(12-21)_第18张图片

NO.19

牛客网sql练习题解(12-21)_第19张图片

select e.last_name, e.first_name, tmp.dept_name
from employees e left join (
  select de.emp_no, d.dept_name
  from dept_emp de left join departments d
  on de.dept_no = d.dept_no
) as tmp
on e.emp_no = tmp.emp_no;

我写的这种事用了自查询,也可以用left join直接两次连接也是可以的

牛客网sql练习题解(12-21)_第20张图片

NO.20

牛客网sql练习题解(12-21)_第21张图片

select (s2.salary - s1.salary) as growth
from salaries s1, salaries s2
where s1.emp_no = 10001 and s1.emp_no = s2.emp_no
and s1.to_date = (
  select to_date
  from salaries
  where emp_no = 10001
  order by to_date
  limit 1
) and s2.from_date = (
  select from_date
  from salaries
  where emp_no = 10001
  order by from_date desc
  limit 1
);

思路是这样的不过可以利用order by或者min max来实现寻找第一次工资和最后一次的工资
牛客网sql练习题解(12-21)_第22张图片

NO.21

这道题是我觉得挺麻烦的一个,怎么说呢,思路挺简单的,写的时候要专心,否则总会有点问题,回去查可是烦人了。
牛客网sql练习题解(12-21)_第23张图片

select first_table.emp_no as emp_no, (current_table.salary - first_table.salary) as growth
from (
    select e.emp_no, s.salary
    from employees e inner join salaries s
    on e.emp_no = s.emp_no
    where e.hire_date = s.from_date
) as first_table inner join (
    select e.emp_no, s.salary
    from employees e inner join salaries s
    on e.emp_no = s.emp_no
    where s.to_date = '9999-01-01'
) as current_table
on first_table.emp_no = current_table.emp_no
order by growth;

主要就是要找到入职的时候的salary,然后在找到current的salary,我觉得应该使用子查询建立临时表这个思路就可以了,但是其中用left join 还是 inner join 还是 全连接+where 看自己的习惯吧。

牛客网sql练习题解(12-21)_第24张图片

大家共勉~

你可能感兴趣的:(数据挖掘,大数据)