【数据库SQL实战】题目1~10答案全解析

目录

1. 查找最晚入职员工的所有信息(单表)

2. 查找入职员工时间排名倒数第三的员工所有信息(单表)

3. 查找当前薪水详情以及部门编号dept_no(多表)

4. 查找所有已经分配部门的员工的last_name和first_name(多表)

5. 查找所有员工的last_name和first_name以及对应部门编号dept_no(多表)、

6. 查找所有员工入职时候的薪水情况(多表)

 7. 查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t(单表)

8. 找出所有员工当前薪水salary情况(单表)

9. 获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary(多表)

10. 获取所有非manager的员工emp_no(多表)


1. 查找最晚入职员工的所有信息(单表)

CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));

select * from employees
where hire_date =(select max(hire_date) from employees)

最晚入职时间等于max(hire_date),得到时间后取出所有记录。

注意:尽量不要使用limit语句,因为可能当天有多条记录。

 

2. 查找入职员工时间排名倒数第三的员工所有信息(单表)

CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));

distinct时间去重:

select * from employees
where hire_date = (select distinct hire_date from employees 
                   order by hire_date desc limit 2,1)

group by时间去重:

select * from employees 
where hire_date = (select hire_date from employees group by hire_date 
                                           order by hire_date desc limit 2,1)

LIMIT m,n : 从第m+1条开始,取n条数据;

LIMIT n : 从第1条开始,取n条数据,是limit(0,n)的缩写。

用desc倒序,取出distinct去重(group by也可以)时间排名倒数的第3天。

3. 查找当前薪水详情以及部门编号dept_no(多表)

CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));

直接从两个表中取出(注意顺序):

select s.*,d.dept_no
from salaries s, dept_manager d 
where s.to_date='9999-01-01'
and d.to_date='9999-01-01'
and s.emp_no=d.emp_no

join方法: 

select s.* ,d.dept_no
from salaries s 
join dept_manager d 
on s.emp_no=d.emp_no
where s.to_date = '9999-01-01'
and d.to_date='9999-01-01'

4. 查找所有已经分配部门的员工的last_name和first_name(多表)

CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));

select e.last_name, e.first_name, d.dept_no
from dept_emp d
inner join employees e 
on d.emp_no=e.emp_no

用inner join方法,查找两张表共有的员工。from后面表的顺序不固定。

5. 查找所有员工的last_name和first_name以及对应部门编号dept_no(多表)、

CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));

select e.last_name, e.first_name, d.dept_no 
from employees e 
left join dept_emp d 
on e.emp_no=d.emp_no

用left join方法,查找emp表中的所有员工,即使dept表中无数据(表示未分配部门)也可以返回。

6. 查找所有员工入职时候的薪水情况(多表)

查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));

内连接:

select s.emp_no, s.salary 
from salaries s 
inner join employees e 
on s.emp_no=e.emp_no 
and s.from_date = e.hire_date 
order by s.emp_no desc

并列查询:

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

 

内连接和并列查询的区别:
内连接是取左右两张表的交集形成一个新表,用FROM并列两张表后仍然还是两张表。

如果还要对新表进行操作则要用内连接。从效率上看应该FROM并列查询比较快,因为不用形成新表。

 7. 查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t(单表)

查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));

select emp_no, count(emp_no) as t 
from salaries
group by emp_no having t >15

用count函数统计次数,而用group by函数进行分类,having是筛选的条件。

8. 找出所有员工当前薪水salary情况(单表)

找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));

distinct:

select distinct salary 
from salaries
where to_date='9999-01-01'
order by salary desc

group by:

select salary from salaries 
where to_date='9999-01-01' 
group by salary 
order by salary desc

 

distinct可以实现,大表一般用distinct效率不高,大数据量的时候都禁止用distinct,建议用group by解决重复问题。

 

9. 获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary(多表)

获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary,当前表示to_date='9999-01-01'
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));

并列查询:

select m.dept_no, m.emp_no, s.salary 
from dept_manager m, salaries s 
where m.to_date='9999-01-01' 
and s.to_date='9999-01-01' 
and s.emp_no = m.emp_no

join连接: 

select m.dept_no, m.emp_no, s.salary
from dept_manager m
join salaries s
on m.emp_no = s.emp_no
and m.to_date = s.to_date
where s.to_date='9999-01-01'

10. 获取所有非manager的员工emp_no(多表)

获取所有非manager的员工emp_no
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));

使用not in:

select emp_no
from employees
where emp_no not in (select emp_no from dept_manager)

left join连接两张表,再从此表中选出dept_no值为NULL对应的emp_no记录

select e.emp_no from employees e left join dept_manager m
on e.emp_no = m.emp_no
where dept_no is null

 

not in在实际使用中会转化成多表连接,而且不使用索引,因此还是用left_join代替会好一点。

你可能感兴趣的:(SQL)