按时来更,感觉题目不是很难,不过我有一个感觉就是虽然题目简单不过如果你只是靠上课知道的那些东西而不亲自动手的话会出现眼高手低的问题。总之,如果大家有兴趣不妨看看,haha。
下面的目录是对应的题号
往期文章:
牛客网sql练习题解 (1-11)
牛客网sql练习题解(12-21)
牛客网sql练习题解(22-32)
牛客网sql练习题解(34-42)
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;
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);
select title, count(*) as t
from titles
group by title
having count()>=2;
select title, count(distinct emp_no) as t
from titles
group by title
having count(distinct emp_no) >= 2
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类型,所以对它的判断需要加上单引号
select *
from employees
where emp_no&1 and last_name <> 'Mary'
order by hire_date desc;
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;
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
-- 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
);
这里我是用的是子查询+distinct
还可以用子查询+group by的方法
不使用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'
)
);
第二种方法
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'
);
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直接两次连接也是可以的
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来实现寻找第一次工资和最后一次的工资
这道题是我觉得挺麻烦的一个,怎么说呢,思路挺简单的,写的时候要专心,否则总会有点问题,回去查可是烦人了。
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 看自己的习惯吧。
大家共勉~