1、查询最晚入职员工的基本信息
# 1、子查询的方式
# 先找出hire_date字段的最大值,在把该值当成条件来查找,还可以扩展为最早等其他限制条件
select * from employees
where hire_date=(select max(hire_date) from employees)
# 2、排序,降序
# 对hire_date字段排序降序,此时最晚的时间排在第一个,再用limit取出
# 此方法有限制,就是取出来的数据唯一,如果最晚来的员工有多人,则取出来还是一人
select * from employees
order by hire_date
limit 0,1
# 3、结合使用
# 首先对hire_date进行排序,在使用hire_date进行限制
select * from employees
where hire_date=(select distinct hire_date form employees order by hire_date limit 0,1)
补充知识点:
limit m,n:表示从第m+1条开始,取n条数据
limit n:表示从第0天开始,取n条数据,是limit(0,n)的缩写
2、查询入职员工时间排名倒数第三的员工所有信息
# 这个问题根据问题1可以直接给出答案
select * from employees
where hire_date=(select distinct hire_date form employees
order by
hire_date limit 2,1)
3、查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号dept_no
select b.*,a.dept_no as dept_no from salaries as b
join dept_manager as a
on b.emp_no=a.emp_no
where b.to_date='9999-01-01'
and a.to_date='9999-01-01'
注意:为什么这里要限制两次时间
-----因为薪水表是按年发的,而题目要查找的是当前的薪水,
所以要过滤掉以前,而dept_manager是因为有领导会离职,
to_date时间不一定是9999-01-01,所以要过滤过离职的领导
4、查找所有已经分配部门的员工的last_name和first_name以及dept_no
select a.last_name,a.first_name,b.dept_no from dept_emp as b
inner join employees as a
on a.emp_no=b.emp_no
5、查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括展示没有分配具体部门的员工
select a.last_name,a.first_name,b.dept_no from
employees as a
left join
dept_emp as b
on b.emp_no=a.emp_no
6、查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序
# 1、方法1:使用inner join连接两张表
select a.emp_no,b.salary from employees as a
inner join salaries as b
on a.emp_no=b.emp_no
and a.hire_date=b.from_date
order by a.emp_no desc
# 2、方法2:使用,连接两张表
select a.emp_no,b.salary from employees a,salaries b
where a.emp_no=b.emp_no
and a.hire_date=b.from_date
order by a.emp_no desc
注意:在使用inner join的时候可以使用,代替连接两张表,
使用a.hire_date=b.from_date是限制在员工入职时候的工资
7、查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t
select a.emp_no,count(*) t from salaries a inner join salaries b
on a.emp_no=b.emp_no and a.to_date = b.from_date
where a.salary < b.salary
group by a.emp_no
having t>15
注意:这里where和having的使用方式
WHERE语句在GROUP BY语句之前;SQL会在分组之前计算WHERE语句。
HAVING语句在GROUP BY语句之后;SQL会在分组之后计算HAVING语句。
由于COUNT()函数不可用于WHERE语句中,故使用HAVING语句来限定t>15的条件
8、找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
select distinct(salary) from salaries
where to_date='9999-01-01'
order by salary desc
# 注意:介绍group by 去重和distinct去重
group by是显示分组的意思,组中只能含有一个词
distinct直接就是去重的意思,不管什么条件
9、获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary,当前表示to_date='9999-01-01'
select a.dept_no,a.emp_no,b.salary from dept_manager a,salaries b
where a.emp_no=b.emp_no
and a.to_date='9999-01-01'
and b.to_date='9999-01-01'
10、获取所有非manager的员工emp_no
# 方法1:使用not in选出在employees但不在dept_manager中的emp_no记录
SELECT emp_no FROM employees
WHERE emp_no NOT IN (SELECT emp_no FROM dept_manager)
# 方法2:先使用LEFT JOIN连接两张表,再从此表中选出dept_no值为NULL对应的emp_no记录
SELECT emp_no FROM (SELECT * FROM employees LEFT JOIN dept_manager
ON employees.emp_no = dept_manager.emp_no)
WHERE dept_no IS NULL
11、获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date='9999-01-01'。
结果第一列给出当前员工的emp_no,第二列给出其manager对应的manager_no
select a.emp_no,b.emp_no as manager_no from dept_emp a
inner join dept_manager b
on a.dept_no=b.dept_no
where a.to_date='9999-01-01'
and b.to_date='9999-01-01'
and a.emp_no<>b.emp_no
# 注意:<>是不等于符号
1、用 INNER JOIN 连接两张表,因为要输出自己的经理,
得知自己与经理的部门要相同,故有限制条件 de.dept_no = dm.dept_no
2、再用 WHERE 限制当前员工与当前经理的条件,
即 dm.to_date 等于 '9999-01-01' 、de.to_date 等于 '9999-01-01' 、
de.emp_no 不等于 dm.emp_no
12、获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
select de.dept_no, de.emp_no, s.salary
from dept_emp de inner join salaries s
on de.emp_no = s.emp_no
and de.to_date = '9999-01-01'
and s.to_date = '9999-01-01'
where s.salary = (select max(s2.salary)
from dept_emp de2 inner join salaries s2
on de2.emp_no = s2.emp_no
and de2.to_date = '9999-01-01'
and s2.to_date = '9999-01-01'
where de2.dept_no = de.dept_no
group by de2.dept_no)
order by de.dept_no
# 解题思路:
先找出每个部门最高薪,需要使用到group by分组来查找最大值,在使用where来
限制每个部门的最高薪。
13、从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
SELECT title, COUNT(title) AS t FROM titles
GROUP BY title HAVING t >= 2
14、从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
注意对于重复的emp_no进行忽略。
select title,count(distinct emp_no)t from titles
group by title
having t>=2
15、查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
select * from employees
where emp_no%2=1
and last_name <> 'Mary'
order by hire_date desc
# 注意:SQL语句中%代表的是除于,不等于,不为可以使用!=,<>,not in 这是
# 限制一个字段的条件
16、统计出当前各个title类型对应的员工当前(to_date='9999-01-01')薪水对应的平均工资。结果给出title以及平均工资avg。
select a.title,avg(b.salary)as avg from titles a
inner join salaries b
on a.emp_no=b.emp_no
and a.to_date='9999-01-01'
and b.to_date='9999-01-01'
group by a.title
17、获取当前(to_date='9999-01-01')薪水第二多的员工的emp_no以及其对应的薪水salary
select emp_no, salary from salaries
where to_date = '9999-01-01' and salary =
(select distinct salary from salaries order by salary desc limit 1,1)
解题思路:
(1) 首先这样可以解决多个人工资相同的问题;
(2) 另外,筛选出第二多的工资时要注意distinct salary,否则不能选出第二多的工资。
18、查找当前薪水(to_date='9999-01-01')排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
select e.emp_no,s.salary,e.last_name,e.first_name
from
employees e
join
salaries s on e.emp_no=s.emp_no
and s.to_date='9999-01-01'
and s.salary =
(
select s1.salary
from
salaries s1
join
salaries s2 on s1.salary<=s2.salary
and s1.to_date='9999-01-01' and s2.to_date='9999-01-01'
group by s1.salary
having count(distinct s2.salary)=2
)
19、查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
SELECT em.last_name, em.first_name, dp.dept_name
FROM (employees AS em LEFT JOIN dept_emp AS de ON em.emp_no = de.emp_no)
LEFT JOIN departments AS dp ON de.dept_no = dp.dept_no
本题思路为运用两次LEFT JOIN连接嵌套
1、第一次LEFT JOIN连接employees表与dept_emp表,得到所有员工的last_name和first_name以及对应的dept_no,也包括暂时没有分配部门的员工
2、第二次LEFT JOIN连接上表与departments表,即连接dept_no与dept_name,得到所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
20、查找员工编号emp_no为10001其自入职以来的薪水salary涨幅值growth
SELECT (MAX(salary)-MIN(salary)) AS growth
FROM salaries WHERE emp_no = '10001'
推荐网站:https://www.nowcoder.com/ta/sql?page=0
随着大数据的时代的到来,数据变得越来越重要,数据可以帮助我们来看清行业的本质,也可以帮助我们更加快速的了解一个行业,关注公众号——DT学说,走进数据的时代