我将分批总结牛客网sql题解,当然leecode也是我比较推荐的sql在线OJ,至于为什么我不写leecode,是因为我不是会员,hahah~
往期文章:
牛客网sql练习题解 (1-11)
牛客网sql练习题解(12-21)
牛客网sql练习题解(22-32)
牛客网sql练习题解(34-42)
select *
from employees
order by hire_date desc
limit 1;
或者是:
select *
from employees
order by hire_date desc
limit 1 offset 0;
或者是:
select *
from employees
order by hire_date desc
limit 0,1;
从第0条记录向后读取一个,也就是第
或者使用子查询
select *
from employees
where hire_date = (
select max(e.hire_date)
from employees e
);
select *
from employees
order by hire_date desc
limit 1 offset 2;
注:
以下的两种方式均表示取2,3,4三条条数据。 1.select* from test LIMIT 1,3; 当limit后面跟两个参数的时候,第一个数表示要跳过的数量,后一位表示要取的数量。 2.select * from test LIMIT 3 OFFSET 1;(在mysql 5以后支持这种写法) 当 limit和offset组合使用的时候,limit后面只能有一个参数,表示要取的的数量,offset表示要跳过的数量 。
当存在重复数据的时候:
select *
from employees
where hire_date = (
select distinct e.hire_date
from employees e
order by e.hire_date desc
limit 1 offset 2
);
SELECT s.*, d.dept_no
FROM salaries AS s , dept_manager AS d
WHERE d.to_date='9999-01-01'
AND s.to_date='9999-01-01'
AND s.emp_no = d.emp_no;
SELECT s.*, d.dept_no
FROM salaries s inner join dept_manager d
on d.emp_no = s.emp_no
WHERE d.to_date='9999-01-01'
AND s.to_date='9999-01-01';
注:
from两个表的顺序如果颠倒就会报错。
我觉得和SQL的执行顺序有关。
具体的题目大致相同,注意join, inner join ,outer join, left join , right join就好
select t1.emp_no, s.salary
from (
select *
from employees e1
group by e1.emp_no
having min(e1.hire_date)
order by e1.emp_no desc
) t1 left join salaries s
on t1.emp_no = s.emp_no and t1.hire_date = s.from_date;
首先我们利用emp_no和最小的hire_date来经employee进行过滤,然后join一下。
但是还有更简单的写法
select e.emp_no, s.salary
from employees e, salaries s
where e.emp_no = s.emp_no and e.hire_date = s.from_date
order by e.emp_no desc;
考察group by 和having的使用
分组聚合函数的考察
select emp_no, count(*) as t
from salaries
group by emp_no
having count(*) > 15;
select s1.emp_no, count(*) as t
from salaries s1 inner join salaries s2
on s1.emp_no = s2.emp_no and s1.to_date = s2.from_date
where s1.salary < s2.salary
group by s1.emp_no
having count(*) > 15;
注:inner Join 和left join的区别
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
inner join(等值连接) 只返回两个表中联结字段相等的行
没什么难度,考察的基本distinct 和 order by 用法
select distinct salary
from salaries
where to_date = '9999-01-01'
order by salary desc;
select dm.dept_no, dm.emp_no, s1.salary
from dept_manager dm, (
select *
from salaries a
where a.to_date = '9999-01-01'
) s1
where dm.emp_no = s1.emp_no and dm.to_date = '9999-01-01';
select distinct emp_no
from employees
where emp_no not in (
select distinct emp_no
from dept_manager
);
这题我觉得注意一下不等于的表示吧
select d.emp_no, dm.emp_no as manager_no
from dept_emp d, dept_manager dm
where d.dept_no = dm.dept_no and dm.to_date = '9999-01-01'
and d.emp_no <> dm.emp_no;
大家共勉~~