Fork me on GitHub

MySQL练习一

查找最晚入职员工的所有信息

1
2
3
4
5
6
7
8
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));

输入描述:

输出描述:

emp_no birth_date first_name last_name gender hire_date
10008 1958-02-19 Saniya Kalloufi M 1994-09-15

解答:

1
select * from employees order by hire_date desc limit 1

查找入职员工时间排名倒数第三的员工所有信息

1
2
3
4
5
6
7
8
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`));

输入描述:

输出描述:

emp_no birth_date first_name last_name gender hire_date
10005 1955-01-21 Kyoichi Maliniak M 1989-09-12

解答:

1
select * from employees order by hire_date desc limit 2, 1

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

1
2
3
4
5
6
7
8
9
10
11
12
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`));

输入描述:

输出描述:

emp_no salary from_date to_date dept_no
10002 72527 2001-08-02 9999-01-01 d001
10004 74057 2001-11-27 9999-01-01 d004
10005 94692 2001-09-09 9999-01-01 d003
10006 43311 2001-08-02 9999-01-01 d002
10010 94409 2001-11-23 9999-01-01 d006

解答:

1
select a.*, b.dept_no from salaries a left join dept_manager b on a.emp_no= b.emp_no where a.to_date= '9999-01-01' and b.to_date= '9999-01-01'

注解:
INNER JOIN 两边表同时有对应的数据,即任何一边缺失数据就不显示。
LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据。
RIGHT JOIN 会读取右边数据表的全部数据,即便左边表无对应数据。

查找所有已经分配部门的员工的last_name和first_name

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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`));

输入描述:

输出描述:

last_name first_name dept_no
Facello Georgi d001
省略 省略 省略
Piveteau Duangkaew d006

解答:

1
select a.last_name, a.first_name, b.dept_no from employees a, dept_emp b where a.emp_no= b.emp_no

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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`));

输入描述:

输出描述:

last_name first_name dept_no
Facello Georgi d001
省略 省略 省略
Sluis Mary NULL(在sqlite中此处为空,MySQL为NULL)

解答:

1
select a.last_name, a.first_name, b.dept_no from employees a left join dept_emp b on a.emp_no= b.emp_no

注解
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。
在使用left join时,on和where条件的区别如下:
1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
2、where条件是在临时表生成后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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`));

输入描述:

输出描述:

emp_no salary
10011 25828
省略 省略
10001 60117

解答:

1
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

查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t

1
2
3
4
5
6
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`));

输入描述:

输出描述:

emp_no t
10001 17
10004 16
10009 18

解答:

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

注解
GROUP BY语法可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表。
SELECT子句中的列名必须为分组列或列函数,列函数对于GROUP BY子句定义的每个组返回一个结果。
GROUP BY子句之后使用Having子句,可应用限定条件进行分组,以便系统仅对满足条件的组返回结果。因此,在GROUP BY子句后面包含了一个HAVING子句。HAVING类似于WHERE(唯一的差别是WHERE过滤行,HAVING过滤组), HAVING支持所有的WHERE操作符。

找出所有员工当前(to_date=’9999-01-01’)具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示

1
2
3
4
5
6
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`));

输入描述:

输出描述:

salary
94692
94409
88958
88070
74057

解答:

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

获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary,当前表示to_date=’9999-01-01’

1
2
3
4
5
6
7
8
9
10
11
12
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`));

输入描述:

输出描述:

dept_no emp_no salary
d001 10002 72527
d004 10004 74057
d003 10005 94692
d002 10006 43311

解答:

1
select a.dept_no, a.emp_no, b.salary from salaries b inner join dept_manager a on a.emp_no= b.emp_no where a.to_date= '9999-01-01' and b.to_date='9999-01-01'

获取所有非manager的员工emp_no

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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`));

输入描述:

输出描述:

emp_no
10001
10003
10007

解答:

1
select a.emp_no from employees a where a.emp_no not in (select b.emp_no from dept_manager b)

注解
employees里的emp_no不在dept_manager出现非manager了,关键使用not in

获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date=’9999-01-01’。结果第一列给出当前员工的emp_no,第二列给出其manager对应的manager_no。

1
2
3
4
5
6
7
8
9
10
11
12
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 `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`));

输入描述:

输出描述:

emp_no manager_no
10001 10002
10003 10004
10009 10010

解答:

1
select a.emp_no, b.emp_no as manager_no from dept_emp a, dept_manager b where a.to_date= '9999-01-01' and b.to_date='9999-01-01' and a.dept_no= b.dept_no and a.emp_no != b.emp_no

他们的职位不一样,部门却是一样的。

获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary

1
2
3
4
5
6
7
8
9
10
11
12
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 `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`));

输入描述:

输出描述:

dept_no emp_no salary
d001 10001 88958
d002 10006 43311
d003 10005 94692

解答:

1
2
3
4
5
6
select a.dept_no,a.emp_no,max(s.salary) as salary
from dept_emp a left join salaries s
on a.emp_no= s.emp_no
where a.to_date='9999-01-01'
and s.to_date='9999-01-01'
group by a.dept_no

从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。

1
2
3
4
5
CREATE TABLE IF NOT EXISTS "titles" (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date DEFAULT NULL);

输入描述:

输出描述:

title t
Assistant Engineer 2
Engineer 4
省略 省略
Staff 3

解答:

1
select title, count(title) as t from titles group by title having t>= 2

having语句可以筛选出满足条件的聚合函数的结果。

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

1
2
3
4
5
CREATE TABLE IF NOT EXISTS "titles" (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date DEFAULT NULL);

输入描述:

输出描述:

title t
Assistant Engineer 2
Engineer 3
省略 省略
Staff 3

解答:

1
select title, count(distinct emp_no) as t from titles group by title having t>= 2

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

1
2
3
4
5
6
7
8
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`));

输入描述:

输出描述:

emp_no birth_date first_name last_name gender hire_date
10011 1953-11-07 Mary Sluis F 1990-01-22
10005 1955-01-21 Kyoichi Maliniak M 1989-09-12
10007 1957-05-23 Tzvetan Zielinski F 1989-02-10
10003 1959-12-03 Parto Bamford M 1986-08-28

解答:

1
select * from employees where emp_no% 2!= 0 and last_name!= "Mary" order by hire_date desc

统计出当前各个title类型对应的员工当前薪水对应的平均工资。结果给出title以及平均工资avg。

1
2
3
4
5
6
7
8
9
10
11
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`));
CREATE TABLE IF NOT EXISTS "titles" (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date DEFAULT NULL);

输入描述:

输出描述:

title avg
Engineer Engineer 94409.0
Senior Engineer 69009.2
Senior Staff 91381.0
Staff 72527.0

解答:

1
select title, avg(salary) from titles left join salaries on titles.emp_no= salaries.emp_no where titles.to_date= "9999-01-01" and salaries.to_date= "9999-01-01" group by titles.title

获取当前(to_date=’9999-01-01’)薪水第二多的员工的emp_no以及其对应的薪水salary

1
2
3
4
5
6
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`));

输入描述:

输出描述:

emp_no salary
10009 94409

解答:

1
select emp_no, salary from salaries where to_date= "9999-01-01" order by salary desc limit 1, 1

查找当前薪水(to_date=’9999-01-01’)排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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`));

输入描述:

输出描述:

emp_no salary last_name first_name
10009 94409 Peac Sumant

解答:

1
2
3
4
select a.emp_no, max(a.salary), b.last_name, b.first_name
from salaries a, employees b where a.emp_no= b.emp_no
and a.to_date= "9999-01-01"
and a.salary not in (select max(salary) from salaries where to_date= "9999-01-01")

查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE `departments` (
`dept_no` char(4) NOT NULL,
`dept_name` varchar(40) NOT NULL,
PRIMARY KEY (`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`));

输入描述:

输出描述:

last_name first_name dept_name
Facello Georgi Marketing
省略 省略 省略
Sluis Mary NULL

解答:

1
select a.last_name, a.first_name, c.dept_name from employees a left join dept_emp b on a.emp_no= b.emp_no left join departments c on b.dept_no= c.dept_no

查找员工编号emp_now为10001其自入职以来的薪水salary涨幅值growth

1
2
3
4
5
6
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`));

输入描述:

输出描述:

growth
28841

解答:

1
2
3
4
select (
(select salary from salaries where emp_no= "10001" order by to_date desc limit 1)-
(select salary from salaries where emp_no= "10001" order by to_date asc limit 1)
) as growth

查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_noy以及其对应的薪水涨幅growth,并按照growth进行升序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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`));

输入描述:

输出描述:

emp_no growth
10011 0
省略 省略
10010 54496
10004 34003

解答:

1
2
3
4
select t1.emp_no, t1.salary- t2.salary as growth from(
(select a.emp_no, b.salary from employees a, salaries b where a.emp_no= b.emp_no and b.to_date= "9999-01-01") as t1,
(select a.emp_no, b.salary from employees a, salaries b where a.emp_no= b.emp_no and b.from_date= a.hire_date) as t2
) where t1.emp_no= t2.emp_no order by growth
Your support will encourage me to continue to create!