DROP TABLE IF EXISTS `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`));
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 emp_no , birth_date , first_name , last_name , gender , hire_date
FROM employees
ORDER BY hire_date DESC LIMIT 1
解决方案-02
SELECT emp_no , birth_date , first_name , last_name , gender , hire_date
FROM employees
WHERE hire_date = (SELECT max(hire_date) FROM employees) LIMIT 1
SELECT * FROM employees ORDER BY hire_date DESC LIMIT 2 , 1
解决方案-02
去除重复的入职时间
SELECT * FROM employees
WHERE
hire_date =
(SELECT distinct hire_date FROM employees ORDER BY hire_date DESC LIMIT 2 , 1)
DROP TABLE IF EXISTS `salaries`;
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL COMMENT '员工编号',
`salary` int(11) NOT NULL COMMENT '薪资' ,
`from_date` date NOT NULL COMMENT '开始时间',
`to_date` date NOT NULL COMMENT '到期时间',
PRIMARY KEY (`emp_no`,`from_date`))
COMMENT '工资表';
INSERT INTO salaries (emp_no , salary ,from_date , to_date)
VALUES
(10001 , 88958 , '2002-06-22' , '9999-01-01'),
(10002 , 72527 , '2001-08-02' , '9999-01-01'),
(10003 , 43311 , '2001-12-01' , '9999-01-01')
DROP TABLE IF EXISTS `dept_manager`;
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL COMMENT '部门编号',
`emp_no` int(11) NOT NULL COMMENT '员工编号',
`to_date` date NOT NULL ,
PRIMARY KEY (`emp_no`,`dept_no`))
COMMENT '部门经理表';
INSERT INTO dept_manager (dept_no , emp_no , to_date)
VALUES
('d001' , 10001 , '9999-01-01'),
('d002' , 10003 , '9999-01-01')
方案-01
SELECT s.emp_no , s.salary , s.from_date , s.to_date, d.dept_no FROM salaries as s
INNER JOIN dept_manager as d ON s.emp_no = d.emp_no
ORDER BY s.emp_no ASC
方案-02
SELECT s.emp_no , s.salary , s.from_date , s.to_date, d.dept_no FROM salaries as s
INNER JOIN dept_manager as d ON s.emp_no = d.emp_no
where s.to_date='9999-01-01' and d.to_date='9999-01-01'
ORDER BY s.emp_no ASC
DROP TABLE IF EXISTS `dept_emp`;
CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL COMMENT '员工编号',
`dept_no` char(4) NOT NULL COMMENT '部门编号',
`from_date` date NOT NULL COMMENT '合同起始时间',
`to_date` date NOT NULL COMMENT '合同终止时间',
PRIMARY KEY (`emp_no`,`dept_no`))
COMMENT '部门表';
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','9999-01-01');
INSERT INTO dept_emp VALUES(10009,'d006','1985-02-18','9999-01-01');
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 DISTINCT e.last_name , e.first_name , d.dept_no FROM employees AS e
INNER JOIN dept_emp AS d ON e.emp_no = d.emp_no
同04题数据库表
SELECT DISTINCT e.last_name , e.first_name , d.dept_no FROM employees AS e
LEFT JOIN dept_emp AS d ON e.emp_no = d.emp_no
DROP TABLE IF EXISTS `salaries`;
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL COMMENT '员工编号',
`salary` int(11) NOT NULL COMMENT '薪资' ,
`from_date` date NOT NULL COMMENT '开始时间',
`to_date` date NOT NULL COMMENT '到期时间',
PRIMARY KEY (`emp_no`,`from_date`))
COMMENT '工资表';
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');
错误点: group by 时,过滤条件用HAVING WHERE
SELECT emp_no, COUNT(DISTINCT from_date) AS t FROM salaries
GROUP BY emp_no
HAVING t > 15
drop table if exists `salaries` ;
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,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01');
INSERT INTO salaries VALUES(10004,43311,'2001-12-01','9999-01-01');
INSERT INTO salaries VALUES(10005,94692,'2001-09-09','9999-01-01');
INSERT INTO salaries VALUES(10006,43311,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10007,88070,'2002-02-07','9999-01-01');
INSERT INTO salaries VALUES(10008,88070,'2002-02-07','9999-01-01');
INSERT INTO salaries VALUES(10009,95409,'2002-02-14','9999-01-01');
INSERT INTO salaries VALUES(10011,25828,'1990-01-22','9999-01-01');
# 这里是创建索引试试,索引是个很好玩的东西
# DROP INDEX salary ON salaries ;
# CREATE INDEX salary ON salaries (salary) ;
SELECT DISTINCT salary FROM salaries ORDER BY salary DESC ;
# DROP INDEX salary ON salaries;
drop table if exists `dept_manager` ;
drop table if exists `employees` ;
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',10003,'1990-08-05','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');
SELECT e.emp_no FROM employees AS e
LEFT JOIN dept_manager as d ON e.emp_no = d.emp_no
WHERE d.emp_no is NULL
drop table if exists `dept_emp` ;
drop table if exists `dept_manager` ;
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,'d002','1995-12-03','9999-01-01');
INSERT INTO dept_manager VALUES('d001',10002,'1996-08-03','9999-01-01');
INSERT INTO dept_manager VALUES('d002',10003,'1990-08-05','9999-01-01');
有两个语法问题:
1. 在 sql_mode=only_full_group_by 时,GROUP BY 后面要加上select后的所有字段
2. DISTINCT 的时候,如果查询多个字段,DISTINCT 后的字段要放在select 后的第一个字段
SELECT e.emp_no AS emp_no , m.emp_no AS manager FROM dept_emp AS e
INNER JOIN dept_manager AS m ON e.dept_no = m.dept_no
WHERE e.emp_no != m.emp_no
GROUP BY e.emp_no , m.emp_no
drop table if exists `dept_emp` ;
drop table if exists `salaries` ;
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`));
INSERT INTO salaries VALUES (10001, 90000, '1986-06-26', '1987-06-26');
INSERT INTO salaries VALUES (10001, 95000, '2002-06-22', '9999-01-01');
INSERT INTO salaries VALUES (10002, 72527, '1996-08-03', '1997-08-03');
INSERT INTO salaries VALUES (10002, 72527, '2000-08-02', '2001-08-02');
INSERT INTO salaries VALUES (10002, 95000, '2001-08-02', '9999-01-01');
INSERT INTO salaries VALUES (10003, 90000, '1996-08-03', '1997-08-03');
INSERT INTO salaries VALUES (10004, 80000, '1996-01-01', '1996-03-01');
INSERT INTO salaries VALUES (10004, 89000, '1996-08-08', '9999-01-01');
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, 'd001', '1996-08-03', '1997-08-03');
INSERT INTO dept_emp VALUES (10004, 'd002', '1996-08-08', '9999-01-01');
1. 获取每个部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary,按照部门编号升序排列,
要充分使用join来进行联合表示
select de.dept_no, emp_no, max_salary FROM dept_emp de
join
(
select dept_no, max(salary) as max_salary FROM salaries s
join dept_emp de on s.emp_no = de.emp_no
where s.to_date = '9999-01-01' and de.to_date = '9999-01-01'
group by dept_no
) t on de.dept_no = t.dept_no where de.to_date = '9999-01-01'
SELECT * from salaries
WHERE salary =
(
SELECT MAX(max_salary) from
(
select dept_no, max(salary) as max_salary FROM salaries s
INNER join dept_emp de on s.emp_no = de.emp_no
where s.to_date = '9999-01-01' and de.to_date = '9999-01-01'
group by dept_no
) AS t
)
drop table if exists `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`));
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','Bezalel','Mary','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');
INSERT INTO employees VALUES(10005,'1953-11-07','Mary','Sluis','F','1990-01-22');
1. 查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
遇到GROUP BY问题,用下面set解决,出现sql_mode = only_full_xx的问题 , 执行下面命令,重新连接就可以了
set @@global.sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
# 解决方案,这里判断奇偶用的位运算, 尽量不要用!= , 用not exits 不用not in
SELECT * FROM employees AS e WHERE e.emp_no & 1 = 1 AND e.last_name <> 'Mary'
ORDER BY hire_date DESC
一共有80到sql题,会在一定时间内做完
现在ORM框架的简便性,慢慢弱化sql能力,我个人觉得sql能力还是很重要的
而且sql能力在面试中也占了很大的分量,所以在牛客网上找点联系题做。
小经验:
关于测试用例问题,在牛客网在线编辑器中,可以设置为联系模式,然后输入一段能编译过但运行失败的sql,然后就可以拷贝出创建数据库语句和测试数据sql语句。免得自己一个一个敲,这个弊端就是,降低自己的提交通过率,不过这也没啥,真正学到东西才是真的,通过率哪些不在意。
注意:
关于题号不连续问题,有的题可以合并成一个题,我就合并了,但是题号按照牛客网题号来的。
答案不是最佳解决方案 ,但是一定是通过测试用例的方案,此篇文章属于长期完成,做完一轮后我会再进行sql优化
之前看到一篇文章,学习一开始不要太较真,不要一下子扎进某个点深入,要先了解整体,造一辆车要先把车造出来,能跑起来再说。跑起来了在考虑优化发动机来提升动力