SQL面试题(来自牛客网)

1、查询最晚入职员工的基本信息

# 1、子查询的方式# 先找出hire_date字段的最大值,在把该值当成条件来查找,还可以扩展为最早等其他限制条件select * from employeeswhere hire_date=(select max(hire_date) from employees)# 2、排序,降序# 对hire_date字段排序降序,此时最晚的时间排在第一个,再用limit取出# 此方法有限制,就是取出来的数据唯一,如果最晚来的员工有多人,则取出来还是一人select * from employees order by hire_datelimit 0,1# 3、结合使用# 首先对hire_date进行排序,在使用hire_date进行限制select * from employeeswhere 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 employeeswhere hire_date=(select distinct hire_date form employees order byhire_date limit 2,1)

3、查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号dept_no

select b.*,a.dept_no as dept_no from salaries as bjoin dept_manager as aon b.emp_no=a.emp_nowhere 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 binner join employees as aon a.emp_no=b.emp_no

 

5、查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括展示没有分配具体部门的员工

select a.last_name,a.first_name,b.dept_no fromemployees as aleft join dept_emp as bon 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 ainner join  salaries as bon a.emp_no=b.emp_noand a.hire_date=b.from_dateorder by a.emp_no desc# 2、方法2:使用,连接两张表select a.emp_no,b.salary from employees a,salaries bwhere a.emp_no=b.emp_noand a.hire_date=b.from_dateorder 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 bon a.emp_no=b.emp_no and a.to_date = b.from_datewhere a.salary < b.salarygroup by a.emp_nohaving 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 salarieswhere 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 bwhere a.emp_no=b.emp_noand 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 employeesWHERE 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_managerON 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 ainner join dept_manager bon a.dept_no=b.dept_nowhere 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_no2、再用 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.salaryfrom dept_emp de inner join salaries son de.emp_no = s.emp_noand 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 titlesGROUP BY title HAVING t >= 2

 

14、从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
注意对于重复的emp_no进行忽略。

select title,count(distinct emp_no)t from titlesgroup by title having t>=2

 

15、查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列

select * from employeeswhere emp_no%2=1and 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  ainner join salaries bon a.emp_no=b.emp_noand 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 salarieswhere 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_namefromemployees ejoin 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_nameFROM (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学说,走进数据的时代

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值