题目所需的数据和表
CREATE TABLE `departments` (
`dept_no` char(4) NOT NULL,
`dept_name` varchar(40) NOT NULL,
PRIMARY KEY (`dept_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `departments` */
insert into `departments`(`dept_no`,`dept_name`) values ('d001','Marketing'),('d002','Finance'),('d003','Human Resources'),('d004','Production'),('d005','Development'),('d006','Quality Management');
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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `dept_emp` */
insert into `dept_emp`(`emp_no`,`dept_no`,`from_date`,`to_date`) values (10001,'d001','1986-06-26','9999-01-01'),(10002,'d001','1996-08-03','9999-01-01'),(10003,'d004','1995-12-03','9999-01-01'),(10004,'d004','1986-12-01','9999-01-01'),(10005,'d003','1989-09-12','9999-01-01'),(10006,'d002','1990-08-05','9999-01-01'),(10007,'d005','1989-02-10','9999-01-01'),(10008,'d005','1998-03-11','2000-07-31'),(10009,'d006','1985-02-18','9999-01-01'),(10010,'d005','1996-11-24','2000-06-26'),(10010,'d006','2000-06-26','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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `dept_manager`(`dept_no`,`emp_no`,`from_date`,`to_date`) values ('d001',10002,'1996-08-03','9999-01-01'),('d004',10004,'1986-12-01','9999-01-01'),('d003',10005,'1989-09-12','9999-01-01'),('d002',10006,'1990-08-05','9999-01-01'),('d005',10010,'1996-11-24','2000-06-26'),('d006',10010,'2000-06-26','9999-01-01');
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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `employees` */
insert into `employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`) values (10001,'1953-09-02','Georgi','Facello','M','1986-06-26'),(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21'),(10003,'1959-12-03','Parto','Bamford','M','1986-08-28'),(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01'),(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12'),(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02'),(10007,'1957-05-23','Tzvetan','Zielinski','F','1989-02-10'),(10008,'1958-02-19','Saniya','Kalloufi','M','1994-09-15'),(10009,'1952-04-19','Sumant','Peac','F','1985-02-18'),(10010,'1963-06-01','Duangkaew','Piveteau','F','1989-08-24'),(10011,'1953-11-07','Mary','Sluis','F','1990-01-22');
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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `salaries` */
insert into `salaries`(`emp_no`,`salary`,`from_date`,`to_date`) values (10001,60117,'1986-06-26','1987-06-26'),(10001,62102,'1987-06-26','1988-06-25'),(10001,66074,'1988-06-25','1989-06-25'),(10001,66596,'1989-06-25','1990-06-25'),(10001,66961,'1990-06-25','1991-06-25'),(10001,71046,'1991-06-25','1992-06-24'),(10001,74333,'1992-06-24','1993-06-24'),(10001,75286,'1993-06-24','1994-06-24'),(10001,75994,'1994-06-24','1995-06-24'),(10001,76884,'1995-06-24','1996-06-23'),(10001,80013,'1996-06-23','1997-06-23'),(10001,81025,'1997-06-23','1998-06-23'),(10001,81097,'1998-06-23','1999-06-23'),(10001,84917,'1999-06-23','2000-06-22'),(10001,85112,'2000-06-22','2001-06-22'),(10001,85097,'2001-06-22','2002-06-22'),(10001,88958,'2002-06-22','9999-01-01'),(10002,72527,'1996-08-03','1997-08-03'),(10002,72527,'1997-08-03','1998-08-03'),(10002,72527,'1998-08-03','1999-08-03'),(10002,72527,'1999-08-03','2000-08-02'),(10002,72527,'2000-08-02','2001-08-02'),(10002,72527,'2001-08-02','9999-01-01'),(10003,40006,'1995-12-03','1996-12-02'),(10003,43616,'1996-12-02','1997-12-02'),(10003,43466,'1997-12-02','1998-12-02'),(10003,43636,'1998-12-02','1999-12-02'),(10003,43478,'1999-12-02','2000-12-01'),(10003,43699,'2000-12-01','2001-12-01'),(10003,43311,'2001-12-01','9999-01-01'),(10004,40054,'1986-12-01','1987-12-01'),(10004,42283,'1987-12-01','1988-11-30'),(10004,42542,'1988-11-30','1989-11-30'),(10004,46065,'1989-11-30','1990-11-30'),(10004,48271,'1990-11-30','1991-11-30'),(10004,50594,'1991-11-30','1992-11-29'),(10004,52119,'1992-11-29','1993-11-29'),(10004,58326,'1994-11-29','1995-11-29'),(10004,60770,'1995-11-29','1996-11-28'),(10004,62566,'1996-11-28','1997-11-28'),(10004,64340,'1997-11-28','1998-11-28'),(10004,67096,'1998-11-28','1999-11-28'),(10004,69722,'1999-11-28','2000-11-27'),(10004,70698,'2000-11-27','2001-11-27'),(10004,74057,'2001-11-27','9999-01-01'),(10005,78228,'1989-09-12','1990-09-12'),(10005,82621,'1990-09-12','1991-09-12'),(10005,83735,'1991-09-12','1992-09-11'),(10005,85572,'1992-09-11','1993-09-11'),(10005,85076,'1993-09-11','1994-09-11'),(10005,86050,'1994-09-11','1995-09-11'),(10005,88448,'1995-09-11','1996-09-10'),(10005,89724,'1997-09-10','1998-09-10'),(10005,90392,'1998-09-10','1999-09-10'),(10005,90531,'1999-09-10','2000-09-09'),(10005,91453,'2000-09-09','2001-09-09'),(10005,94692,'2001-09-09','9999-01-01'),(10006,43311,'1990-08-05','1991-08-05'),(10006,43311,'1991-08-05','1992-08-04'),(10006,43311,'1992-08-04','1993-08-04'),(10006,43311,'1993-08-04','1994-08-04'),(10006,43311,'1994-08-04','1995-08-04'),(10006,43311,'1995-08-04','1996-08-03'),(10006,43311,'1996-08-03','1997-08-03'),(10006,43311,'1997-08-03','1998-08-03'),(10006,43311,'1998-08-03','1999-08-03'),(10006,43311,'1999-08-03','2000-08-02'),(10006,43311,'2000-08-02','2001-08-02'),(10006,43311,'2001-08-02','9999-01-01'),(10007,56724,'1989-02-10','1990-02-10'),(10007,60740,'1990-02-10','1991-02-10'),(10007,62745,'1991-02-10','1992-02-10'),(10007,63475,'1992-02-10','1993-02-09'),(10007,63208,'1993-02-09','1994-02-09'),(10007,64563,'1994-02-09','1995-02-09'),(10007,68833,'1995-02-09','1996-02-09'),(10007,70220,'1996-02-09','1997-02-08'),(10007,73362,'1997-02-08','1998-02-08'),(10007,75582,'1998-02-08','1999-02-08'),(10007,79513,'1999-02-08','2000-02-08'),(10007,80083,'2000-02-08','2001-02-07'),(10007,84456,'2001-02-07','2002-02-07'),(10007,88070,'2002-02-07','9999-01-01'),(10008,46671,'1998-03-11','1999-03-11'),(10008,48584,'1999-03-11','2000-03-10'),(10008,52668,'2000-03-10','2000-07-31'),(10009,60929,'1985-02-18','1986-02-18'),(10009,64604,'1986-02-18','1987-02-18'),(10009,64780,'1987-02-18','1988-02-18'),(10009,66302,'1988-02-18','1989-02-17'),(10009,69042,'1989-02-17','1990-02-17'),(10009,70889,'1990-02-17','1991-02-17'),(10009,71434,'1991-02-17','1992-02-17'),(10009,74612,'1992-02-17','1993-02-16'),(10009,76518,'1993-02-16','1994-02-16'),(10009,78335,'1994-02-16','1995-02-16'),(10009,80944,'1995-02-16','1996-02-16');
CREATE TABLE `titles` (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `titles` */
insert into `titles`(`emp_no`,`title`,`from_date`,`to_date`) values (10001,'Senior Engineer','1986-06-26','9999-01-01'),(10002,'Staff','1996-08-03','9999-01-01'),(10003,'Senior Engineer','1995-12-03','9999-01-01'),(10004,'Engineer','1986-12-01','1995-12-01'),(10004,'Senior Engineer','1995-12-01','9999-01-01'),(10005,'Senior Staff','1996-09-12','9999-01-01'),(10005,'Staff','1989-09-12','1996-09-12'),(10006,'Senior Engineer','1990-08-05','9999-01-01'),(10007,'Senior Staff','1996-02-11','9999-01-01'),(10007,'Staff','1989-02-10','1996-02-11'),(10008,'Assistant Engineer','1998-03-11','2000-07-31'),(10009,'Assistant Engineer','1985-02-18','1990-02-18'),(10009,'Engineer','1990-02-18','1995-02-18'),(10009,'Senior Engineer','1995-02-18','9999-01-01'),(10010,'Engineer','1996-11-24','9999-01-01'),(10010,'Engineer','1996-11-24','9999-01-01');
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
order by hire_date desc
limit 1;
*/
/* 使用limit 与 offset关键字 */
/*
select * from employees
order by hire_date desc
limit 1 offset 0;
*/
/* 使用limit关键字 从第0条记录 向后读取一个,也就是第一条记录 */
/*
select * from employees
order by hire_date desc
limit 0,1;
*/
/* 使用子查询,最后一天的时间有多个员工信息 */
/*
select * from employees
where hire_date = (select max(hire_date) from employees);
*/
注,最晚入职的不一定是一个人,可能是几个,用子查询语句,找出最晚入职的日期
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`));
答案(答案不唯一,仅限参考)
(当有多位员工属于这种情况时)
SELECT *
FROM employees
WHERE hire_date = (
SELECT DISTINCT hire_date -- SELECT DISTINCT 列名称 FROM 表名称, 关键词 DISTINCT 用于返回唯一不同的值。
FROM employees
ORDER BY hire_date DESC -- 倒序
LIMIT 1 OFFSET 2 -- 去掉排名倒数第一第二的时间,取倒数第三
);
LIMIT m,n : 表示从第m+1条开始,取n条数据;
LIMIT n : 表示从第0条开始,取n条数据,是limit(0,n)的缩写。
(1)首先需要加distinct去重。
假设 5-23(入职最晚日期)入职的有a,b,c 3人;
5-22(入职第二晚日期)入职的有d,e 2人;
5-21(入职倒数第三晚)入职的有f,g,h 3人;
5-21前入职的若干...
若 不加distinct去重,那么按照日期倒序,limit 2,1(从倒数第2行开始,取一条数据)的查询结果为 5-23
加了distinct去重,会按入职日期进行分组,多个相同入职日期会分为一组,这样limit 2,1的结果即为 5-21。
(2)外层的where条件中根据子查询查出的倒数第三晚入职的日期,就能查询出符合条件的员工信息。
SELECT * FROM employees
ORDER BY hire_date DESC
LIMIT 1 offset 2;
3.题目描述
获取所有部门当前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));
本题主要是要区分谁是主表,谁是从表,根据输出salaries是主表,dept_manager是从表
效果展示
```java
代码1
select s.*,d.dept_no
from salaries as s,dept_manager as d
where date(s.to_date) = ‘9999-01-01’
and date(d.to_date) = ‘9999-01-01’
and s.emp_no = d.emp_no ;
运行时间:16ms
占用内存:3296k
代码2
select s.*,d.dept_no
from salaries as s,dept_manager as d
where s.to_date = ‘9999-01-01’
and d.to_date = ‘9999-01-01’
and s.emp_no = d.emp_no ;
运行时间:20ms
占用内存:3432k
select s.* ,d.dept_no -- 声明 s.ept_no 和 s.ept_no 为要查询的字段
from salaries as s -- as 将s别名赋值给 salaries表
join dept_manager as d -- join...on 联结
on s.emp_no=d.emp_no
where s.to_date = '9999-01-01' and d.to_date='9999-01-01';
运行时间:16ms
占用内存:3320k
使用了join …on 的联结方法
4.题目描述
查找所有已经分配部门的员工的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`));
测试数据
INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01');
INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01');
INSERT INTO dept_emp VALUES(10003,'d004','1995-12-03','9999-01-01');
INSERT INTO dept_emp VALUES(10004,'d004','1986-12-01','9999-01-01');
INSERT INTO dept_emp VALUES(10005,'d003','1989-09-12','9999-01-01');
INSERT INTO dept_emp VALUES(10006,'d002','1990-08-05','9999-01-01');
INSERT INTO dept_emp VALUES(10007,'d005','1989-02-10','9999-01-01');
INSERT INTO dept_emp VALUES(10008,'d005','1998-03-11','2000-07-31');
INSERT INTO dept_emp VALUES(10009,'d006','1985-02-18','9999-01-01');
INSERT INTO dept_emp VALUES(10010,'d005','1996-11-24','2000-06-26');
INSERT INTO dept_emp VALUES(10010,'d006','2000-06-26','9999-01-01');
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');
INSERT INTO employees VALUES(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12');
INSERT INTO employees VALUES(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02');
INSERT INTO employees VALUES(10007,'1957-05-23','Tzvetan','Zielinski','F','1989-02-10');
INSERT INTO employees VALUES(10008,'1958-02-19','Saniya','Kalloufi','M','1994-09-15');
INSERT INTO employees VALUES(10009,'1952-04-19','Sumant','Peac','F','1985-02-18');
INSERT INTO employees VALUES(10010,'1963-06-01','Duangkaew','Piveteau','F','1989-08-24');
INSERT INTO employees VALUES(10011,'1953-11-07','Mary','Sluis','F','1990-01-22');
内连接:隐式
select e.last_name,e.first_name,d.dept_no
from employees e,dept_emp d
where d.emp_no = e.emp_no;
运行时间:15ms
占用内存:3424k
内连接:显式
select e.last_name,e.first_name,d.dept_no
from employees e join dept_emp d on
d.emp_no = e.emp_no;
运行时间:14ms
占用内存:3552k
使用左连接
select last_name, first_name, dept_no
from employees as e
left join dept_emp as d
on d.emp_no = e.emp_no
where d.dept_no not null;
运行时间:14ms
占用内存:3428k
注意:因为左连接会自动未分配部门的员工的dept_no字段补null,所以要用not null剔除
``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`));`
测试数据
INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01');
INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01');
INSERT INTO dept_emp VALUES(10003,'d004','1995-12-03','9999-01-01');
INSERT INTO dept_emp VALUES(10004,'d004','1986-12-01','9999-01-01');
INSERT INTO dept_emp VALUES(10005,'d003','1989-09-12','9999-01-01');
INSERT INTO dept_emp VALUES(10006,'d002','1990-08-05','9999-01-01');
INSERT INTO dept_emp VALUES(10007,'d005','1989-02-10','9999-01-01');
INSERT INTO dept_emp VALUES(10008,'d005','1998-03-11','2000-07-31');
INSERT INTO dept_emp VALUES(10009,'d006','1985-02-18','9999-01-01');
INSERT INTO dept_emp VALUES(10010,'d005','1996-11-24','2000-06-26');
INSERT INTO dept_emp VALUES(10010,'d006','2000-06-26','9999-01-01');
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');
INSERT INTO employees VALUES(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12');
INSERT INTO employees VALUES(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02');
INSERT INTO employees VALUES(10007,'1957-05-23','Tzvetan','Zielinski','F','1989-02-10');
INSERT INTO employees VALUES(10008,'1958-02-19','Saniya','Kalloufi','M','1994-09-15');
INSERT INTO employees VALUES(10009,'1952-04-19','Sumant','Peac','F','1985-02-18');
INSERT INTO employees VALUES(10010,'1963-06-01','Duangkaew','Piveteau','F','1989-08-24');
INSERT INTO employees VALUES(10011,'1953-11-07','Mary','Sluis','F','1990-01-22');
答案:
-- 左外连接查询的是左表所有的数据以及其交集部分
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;
运行时间:22ms
占用内存:3280k
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`));
输入描述:
-- 方法1:获取salaries中from_data中最小的对应的salary和emp_no,因为salaries可能涨薪,所以这张表一个员工可能有多条记录。
SELECT
emp_no, -- 分组字段
salary -- 查找的字段
FROM
salaries -- 查找薪水表
GROUP BY
emp_no -- 以emp_no为分组字段
HAVING
min( from_date )
ORDER BY
emp_no DESC -- 降序
方法二:hire_data时间和from_data时间一致
SELECT
e.emp_no,
s.salary
FROM
employees AS e
INNER JOIN salaries AS s ON e.emp_no = s.emp_no
AND e.hire_date = s.from_date
ORDER BY
e.emp_no DESC
方法三:hire_data时间和from_data时间一致
SELECT
e.emp_no,
s.salary
FROM
employees AS e,
salaries AS s
WHERE
e.emp_no = s.emp_no
AND e.hire_date = s.from_date
ORDER BY
e.emp_no DESC
7.题目描述
查找薪水变动超过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`));
测试数据
INSERT INTO salaries VALUES(10001,60117,'1986-06-26','1987-06-26');
INSERT INTO salaries VALUES(10001,62102,'1987-06-26','1988-06-25');
INSERT INTO salaries VALUES(10001,66074,'1988-06-25','1989-06-25');
INSERT INTO salaries VALUES(10001,66596,'1989-06-25','1990-06-25');
INSERT INTO salaries VALUES(10001,66961,'1990-06-25','1991-06-25');
INSERT INTO salaries VALUES(10001,71046,'1991-06-25','1992-06-24');
INSERT INTO salaries VALUES(10001,74333,'1992-06-24','1993-06-24');
INSERT INTO salaries VALUES(10001,75286,'1993-06-24','1994-06-24');
INSERT INTO salaries VALUES(10001,75994,'1994-06-24','1995-06-24');
INSERT INTO salaries VALUES(10001,76884,'1995-06-24','1996-06-23');
INSERT INTO salaries VALUES(10001,80013,'1996-06-23','1997-06-23');
INSERT INTO salaries VALUES(10001,81025,'1997-06-23','1998-06-23');
INSERT INTO salaries VALUES(10001,81097,'1998-06-23','1999-06-23');
INSERT INTO salaries VALUES(10001,84917,'1999-06-23','2000-06-22');
INSERT INTO salaries VALUES(10001,85112,'2000-06-22','2001-06-22');
INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1996-08-03','1997-08-03');
INSERT INTO salaries VALUES(10002,72527,'1997-08-03','1998-08-03');
INSERT INTO salaries VALUES(10002,72527,'1998-08-03','1999-08-03');
INSERT INTO salaries VALUES(10002,72527,'1999-08-03','2000-08-02');
INSERT INTO salaries VALUES(10002,72527,'2000-08-02','2001-08-02');
INSERT INTO salaries VALUES(10002,72527,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10003,40006,'1995-12-03','1996-12-02');
INSERT INTO salaries VALUES(10003,43616,'1996-12-02','1997-12-02');
INSERT INTO salaries VALUES(10003,43466,'1997-12-02','1998-12-02');
INSERT INTO salaries VALUES(10003,43636,'1998-12-02','1999-12-02');
INSERT INTO salaries VALUES(10003,43478,'1999-12-02','2000-12-01');
INSERT INTO salaries VALUES(10003,43699,'2000-12-01','2001-12-01');
INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01'); INSERT INTO salaries VALUES(10004,40054,'1986-12-01','1987-12-01'); INSERT INTO salaries VALUES(10004,42283,'1987-12-01','1988-11-30'); INSERT INTO salaries VALUES(10004,42542,'1988-11-30','1989-11-30'); INSERT INTO salaries VALUES(10004,46065,'1989-11-30','1990-11-30'); INSERT INTO salaries VALUES(10004,48271,'1990-11-30','1991-11-30'); INSERT INTO salaries VALUES(10004,50594,'1991-11-30','1992-11-29'); INSERT INTO salaries VALUES(10004,52119,'1992-11-29','1993-11-29'); INSERT INTO salaries VALUES(10004,54693,'1993-11-29','1994-11-29'); INSERT INTO salaries VALUES(10004,58326,'1994-11-29','1995-11-29'); INSERT INTO salaries VALUES(10004,60770,'1995-11-29','1996-11-28'); INSERT INTO salaries VALUES(10004,62566,'1996-11-28','1997-11-28'); INSERT INTO salaries VALUES(10004,64340,'1997-11-28','1998-11-28'); INSERT INTO salaries VALUES(10004,67096,'1998-11-28','1999-11-28'); INSERT INTO salaries VALUES(10004,69722,'1999-11-28','2000-11-27'); INSERT INTO salaries VALUES(10004,70698,'2000-11-27','2001-11-27'); INSERT INTO salaries VALUES(10004,74057,'2001-11-27','9999-01-01'); INSERT INTO salaries VALUES(10005,78228,'1989-09-12','1990-09-12'); INSERT INTO salaries VALUES(10005,82621,'1990-09-12','1991-09-12'); INSERT INTO salaries VALUES(10005,83735,'1991-09-12','1992-09-11'); INSERT INTO salaries VALUES(10005,85572,'1992-09-11','1993-09-11'); INSERT INTO salaries VALUES(10005,85076,'1993-09-11','1994-09-11'); INSERT INTO salaries VALUES(10005,86050,'1994-09-11','1995-09-11'); INSERT INTO salaries VALUES(10005,88448,'1995-09-11','1996-09-10'); INSERT INTO salaries VALUES(10005,88063,'1996-09-10','1997-09-10'); INSERT INTO salaries VALUES(10005,89724,'1997-09-10','1998-09-10'); INSERT INTO salaries VALUES(10005,90392,'1998-09-10','1999-09-10'); INSERT INTO salaries VALUES(10005,90531,'1999-09-10','2000-09-09'); INSERT INTO salaries VALUES(10005,91453,'2000-09-09','2001-09-09'); INSERT INTO salaries VALUES(10005,94692,'2001-09-09','9999-01-01'); INSERT INTO salaries VALUES(10006,43311,'1990-08-05','1991-08-05'); INSERT INTO salaries VALUES(10006,43311,'1991-08-05','1992-08-04'); INSERT INTO salaries VALUES(10006,43311,'1992-08-04','1993-08-04'); INSERT INTO salaries VALUES(10006,43311,'1993-08-04','1994-08-04'); INSERT INTO salaries VALUES(10006,43311,'1994-08-04','1995-08-04'); INSERT INTO salaries VALUES(10006,43311,'1995-08-04','1996-08-03'); INSERT INTO salaries VALUES(10006,43311,'1996-08-03','1997-08-03'); INSERT INTO salaries VALUES(10006,43311,'1997-08-03','1998-08-03'); INSERT INTO salaries VALUES(10006,43311,'1998-08-03','1999-08-03'); INSERT INTO salaries VALUES(10006,43311,'1999-08-03','2000-08-02'); INSERT INTO salaries VALUES(10006,43311,'2000-08-02','2001-08-02'); INSERT INTO salaries VALUES(10006,43311,'2001-08-02','9999-01-01'); INSERT INTO salaries VALUES(10007,56724,'1989-02-10','1990-02-10'); INSERT INTO salaries VALUES(10007,60740,'1990-02-10','1991-02-10'); INSERT INTO salaries VALUES(10007,62745,'1991-02-10','1992-02-10'); INSERT INTO salaries VALUES(10007,63475,'1992-02-10','1993-02-09'); INSERT INTO salaries VALUES(10007,63208,'1993-02-09','1994-02-09'); INSERT INTO salaries VALUES(10007,64563,'1994-02-09','1995-02-09'); INSERT INTO salaries VALUES(10007,68833,'1995-02-09','1996-02-09'); INSERT INTO salaries VALUES(10007,70220,'1996-02-09','1997-02-08'); INSERT INTO salaries VALUES(10007,73362,'1997-02-08','1998-02-08'); INSERT INTO salaries VALUES(10007,75582,'1998-02-08','1999-02-08'); INSERT INTO salaries VALUES(10007,79513,'1999-02-08','2000-02-08'); INSERT INTO salaries VALUES(10007,80083,'2000-02-08','2001-02-07'); INSERT INTO salaries VALUES(10007,84456,'2001-02-07','2002-02-07'); INSERT INTO salaries VALUES(10007,88070,'2002-02-07','9999-01-01'); INSERT INTO salaries VALUES(10008,46671,'1998-03-11','1999-03-11'); INSERT INTO salaries VALUES(10008,48584,'1999-03-11','2000-03-10'); INSERT INTO salaries VALUES(10008,52668,'2000-03-10','2000-07-31'); INSERT INTO salaries VALUES(10009,60929,'1985-02-18','1986-02-18'); INSERT INTO salaries VALUES(10009,64604,'1986-02-18','1987-02-18'); INSERT INTO salaries VALUES(10009,64780,'1987-02-18','1988-02-18'); INSERT INTO salaries VALUES(10009,66302,'1988-02-18','1989-02-17'); INSERT INTO salaries VALUES(10009,69042,'1989-02-17','1990-02-17'); INSERT INTO salaries VALUES(10009,70889,'1990-02-17','1991-02-17'); INSERT INTO salaries VALUES(10009,71434,'1991-02-17','1992-02-17'); INSERT INTO salaries VALUES(10009,74612,'1992-02-17','1993-02-16'); INSERT INTO salaries VALUES(10009,76518,'1993-02-16','1994-02-16'); INSERT INTO salaries VALUES(10009,78335,'1994-02-16','1995-02-16');
INSERT INTO salaries VALUES(10009,80944,'1995-02-16','1996-02-16'); INSERT INTO salaries VALUES(10009,82507,'1996-02-16','1997-02-15'); INSERT INTO salaries VALUES(10009,85875,'1997-02-15','1998-02-15');
INSERT INTO salaries VALUES(10009,89324,'1998-02-15','1999-02-15');
INSERT INTO salaries VALUES(10009,90668,'1999-02-15','2000-02-15');
INSERT INTO salaries VALUES(10009,93507,'2000-02-15','2001-02-14');
INSERT INTO salaries VALUES(10009,94443,'2001-02-14','2002-02-14');
效果演示
select
emp_no,count(emp_no) t
from salaries
group by emp_no having t > 15; -- having 条件
8.题目描述
找出所有员工当前(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`));
答案
select distinct salary -- distinct 去重
from salaries
where to_date='9999-01-01'
order by salary desc
9.题目描述
获取所有部门当前(dept_manager.to_date=‘9999-01-01’)manager的当前(salaries.to_date=‘9999-01-01’)薪水情况,给出dept_no, emp_no以及salary(请注意,同一个人可能有多条薪水情况记录)
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 d.dept_no, d.emp_no, s.salary
FROM salaries AS s INNER JOIN dept_manager AS d
ON d.emp_no = s.emp_no
AND d.to_date = '9999-01-01'
AND s.to_date = '9999-01-01'
10.题目描述
获取所有非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`));
测试数据
INSERT INTO dept_manager VALUES('d001',10002,'1996-08-03','9999-01-01');
INSERT INTO dept_manager VALUES('d002',10006,'1990-08-05','9999-01-01');
INSERT INTO dept_manager VALUES('d003',10005,'1989-09-12','9999-01-01');
INSERT INTO dept_manager VALUES('d004',10004,'1986-12-01','9999-01-01');
INSERT INTO dept_manager VALUES('d005',10010,'1996-11-24','2000-06-26');
INSERT INTO dept_manager VALUES('d006',10010,'2000-06-26','9999-01-01');
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');
INSERT INTO employees VALUES(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12');
INSERT INTO employees VALUES(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02');
INSERT INTO employees VALUES(10007,'1957-05-23','Tzvetan','Zielinski','F','1989-02-10');
INSERT INTO employees VALUES(10008,'1958-02-19','Saniya','Kalloufi','M','1994-09-15');
INSERT INTO employees VALUES(10009,'1952-04-19','Sumant','Peac','F','1985-02-18');
INSERT INTO employees VALUES(10010,'1963-06-01','Duangkaew','Piveteau','F','1989-08-24');
INSERT INTO employees VALUES(10011,'1953-11-07','Mary','Sluis','F','1990-01-22');
-- 分析非manager的员工dept_no 为空
-- 左外连接:查询左表所有内容以及和右表的交集内容
select e.emp_no
from employees e left join dept_manager d on d.emp_no = e.emp_no
where d.dept_no is null
11.题目描述
获取所有员工当前的(dept_manager.to_date=‘9999-01-01’)manager,如果员工是manager的话不显示(也就是如果当前的manager是自己的话结果不显示)。输出结果第一列给出当前员工的emp_no,第二列给出其manager对应的emp_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 `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`));
测试数据
INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01');
INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01');
INSERT INTO dept_emp VALUES(10003,'d004','1995-12-03','9999-01-01');
INSERT INTO dept_emp VALUES(10004,'d004','1986-12-01','9999-01-01');
INSERT INTO dept_emp VALUES(10005,'d003','1989-09-12','9999-01-01');
INSERT INTO dept_emp VALUES(10006,'d002','1990-08-05','9999-01-01');
INSERT INTO dept_emp VALUES(10007,'d005','1989-02-10','9999-01-01');
INSERT INTO dept_emp VALUES(10008,'d005','1998-03-11','2000-07-31');
INSERT INTO dept_emp VALUES(10009,'d006','1985-02-18','9999-01-01');
INSERT INTO dept_emp VALUES(10010,'d005','1996-11-24','2000-06-26');
INSERT INTO dept_emp VALUES(10010,'d006','2000-06-26','9999-01-01');
INSERT INTO dept_manager VALUES('d001',10002,'1996-08-03','9999-01-01');
INSERT INTO dept_manager VALUES('d002',10006,'1990-08-05','9999-01-01');
INSERT INTO dept_manager VALUES('d003',10005,'1989-09-12','9999-01-01');
INSERT INTO dept_manager VALUES('d004',10004,'1986-12-01','9999-01-01');
INSERT INTO dept_manager VALUES('d005',10010,'1996-11-24','2000-06-26');
INSERT INTO dept_manager VALUES('d006',10010,'2000-06-26','9999-01-01');
-- 获取所有员工当前的(dept_manager.to_date='9999-01-01')manager,如果员工是manager的话不显示(也就是如果当前的manager是自己的话结果不显示)。
-- 输出结果第一列给出当前员工的emp_no,第二列给出其manager对应的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
-- 3、为了增强代码可读性,将 dept_emp 用别名 de 代替,dept_manager 用 dm 代替,最后根据题意将 de.emp_no 用别名 manager_no 代替后输出
--
SELECT de.emp_no, dm.emp_no AS manager_no
FROM dept_emp AS de INNER JOIN dept_manager AS dm
ON de.dept_no = dm.dept_no
WHERE dm.to_date = '9999-01-01' AND de.to_date = '9999-01-01' AND de.emp_no <> dm.emp_no
-- 答案2 左外连接
select de.emp_no, dm.emp_no as manage_no
from dept_emp de left join dept_manager dm
on de.dept_no = dm.dept_no
where de.to_date = '9999-01-01' and dm.to_date = '9999-01-01' and de.emp_no <> dm.emp_no;
12.题目描述
有一个员工表dept_emp简况如下:
有一个薪水表salaries简况如下:
获取所有部门中员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary,按照部门编号升序排列,以上例子输出如下:
此题常见漏洞:
1.emp_no直接和group by dept_no一起使用,拿到了最大salary但是存在emp_no取值其实与salary不匹配的问题
2. 先使用group by获得最高salary,再去用最高salary匹配两表返回dept_no,emp_no信息。
这存在A部门的最高薪水,等于B部门非最高薪水时,B部门的非最高薪水也会被显示出来。
'解法一:(如果同部门有多条同等最大salary,一起显示出来)'
SELECT
r.dept_no,
ss.emp_no,
r.maxSalary
FROM
(
SELECT
d.dept_no,
max( s.salary ) AS maxSalary
FROM
dept_emp d,
salaries s
WHERE
d.emp_no = s.emp_no
AND d.to_date = '9999-01-01'
AND s.to_date = '9999-01-01'
GROUP BY
d.dept_no
) AS r,
salaries ss,
dept_emp dd
WHERE
r.maxSalary = ss.salary
AND r.dept_no = dd.dept_no
AND dd.emp_no = ss.emp_no
AND ss.to_date = '9999-01-01'
AND dd.to_date = '9999-01-01'
ORDER BY
r.dept_no ASC
13.题目描述
有一个员工表employees简况如下:
建表语句如下:
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`));
请你查找employees表所有emp_no为奇数.
且last_name不为Mary的员工信息.并按照hire_date逆序排列.
以上例子查询结果如下:
解法1:
SELECT
*
FROM
employees
WHERE
emp_no % 2 = 1
AND last_name != 'Mary'
order by hire_date desc
解法二:
SELECT
*
FROM
employees
WHERE
emp_no & 1=1
AND last_name != 'Mary'
order by hire_date desc
解法三:
SELECT
*
FROM
employees
WHERE
MOD(emp_no,2)=1
AND last_name != 'Mary'
order by hire_date desc
14.题目描述
有一个员工职称表titles简况如下:
有一个薪水表salaries简况如下:
CREATE TABLE titles (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date DEFAULT NULL);
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`));
请你统计出各个title类型对应的员工薪水对应的平均工资avg。
结果给出title以及平均工资avg,并且以avg升序排序,以上例子输出如下:
解法1:
SELECT
t.title,
AVG(s.salary) avg
FROM
titles t
inner JOIN salaries s ON s.emp_no = t.emp_no
GROUP BY t.title
order by avg asc
15.题目描述
有一个薪水表salaries简况如下
请你获取薪水第二多的员工的emp_no以及其对应的薪水salary
解法一
SELECT
emp_no,
salary
FROM
salaries
WHERE
to_date = '9999-01-01'
AND salary = ( SELECT distinct salary FROM salaries WHERE to_date = '9999-01-01' ORDER BY salary DESC LIMIT 1, 1 )
ORDER BY
salary DESC
解法二:
SELECT
emp_no,
salary
FROM
salaries
WHERE
to_date = '9999-01-01'
AND salary = ( SELECT salary FROM salaries GROUP BY salary ORDER BY salary DESC LIMIT 1 OFFSET 1 );
16.题目描述
有一个员工表employees简况如下:
有一个薪水表salaries简况如下:
请你查找薪水排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不能使用order by完成。
以上例子输出为:
解法1:
-- 1.先查薪水排名第一的
SELECT
max(salary) salary
FROM
salaries
WHERE
to_date = '9999-01-01'
-- 2.根据最高薪水,查询薪水排名第二的
SELECT
max(salary) salary
FROM
salaries
WHERE
salary != ( SELECT max( salary ) salary FROM salaries WHERE to_date = '9999-01-01' )
--3.根据第二高的薪水查询
SELECT
s.emp_no,
s.salary,
e.last_name,
e.first_name
FROM
salaries s
INNER JOIN employees e ON s.emp_no = e.emp_no
WHERE
s.salary = ( SELECT max( salary ) salary FROM salaries WHERE salary != ( SELECT max( salary ) salary FROM salaries WHERE to_date = '9999-01-01' ) )
and s.to_date = '9999-01-01'
解法二:
SELECT
s.emp_no,
s.salary,
e.last_name,
e.first_name
FROM
salaries s
JOIN employees e ON s.emp_no = e.emp_no
WHERE
s.salary = (
SELECT
s1.salary
FROM
salaries s1
JOIN salaries s2 -- 自连接查询
ON s1.salary <= s2.salary
WHERE
s1.to_date = '9999-01-01'
AND s2.to_date = '9999-01-01'
GROUP BY
s1.salary -- 当s1<=s2链接并以s1.salary分组时一个s1会对应多个s2
HAVING
count( DISTINCT s2.salary ) = 2 -- (去重之后的数量就是对应的名次)
)
AND s.to_date = '9999-01-01'