如何用MySQL存储函数求3个数中的最大数 sql求三个数中的最大数_牛客网


SQL练习题来源是牛客网



十七题:

  • 查找当前薪水(to_date='9999-01-01')排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
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 e.emp_no, MAX(s.salary)as salary, e.last_name,e.first_name 
FROM employees as e INNER JOIN salaries as s  
ON e.emp_no = s.emp_no 
WHERE s.to_date='9999-01-01'
AND s.salary is not (SELECT MAX(salary) FROM salaries 
WHERE to_date='9999-01-01');


本题做法很多,主要思想为多层SELECT嵌套与MAX()函数结合
1、先利用MAX()函数找出salaries中当前薪水最高者,即SELECT MAX(salary) FROM salaries WHERE to_date = '9999-01-01'
2、再利用INNER JOIN连接employees与salaries表,限定条件为【同一员工】e.emp_no = s.emp_no、【当前】s.to_date = '9999-01-01'与【非薪水最高】s.salary is not (SELECT MAX(salary) FROM salaries WHERE to_date = '9999-01-01')
3、在以上限制条件下找薪水最高者,即为所有员工薪水的次高者

第十八题

  • 查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
表一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`));

答案:


SELECT E.last_name,E.first_name,P.dept_name 
FROM (employees AS E LEFT JOIN dept_emp AS D 
ON E.emp_no = D.emp_no) LEFT JOIN departments AS P 
ON D.dept_no = P.dept_no;

本题思路为运用两次LEFT JOIN连接嵌套【 这个是三个表的关联,需要注意使用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,也包括暂时没有分配部门的员工。

十九题:

题目描述

  • 查找员工编号emp_no为10001其自入职以来的薪水salary涨幅值growth
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 (MAX(salary)-MIN(salary)) as growth 
FROM salaries 
WHERE emp_no = '10001';


本题严谨的思路如下:
1、先分别找到emp_no=10001的员工的第一次工资记录与最后一次工资记录
2、再将最后一次工资记录减去第一次工资记录得到入职以来salary的涨幅,最后用别名growth代替
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
本题的另一种解法也能通过测试,但实际上不严谨,只有在员工最后一条工资记录为最大值时成立,如果最后一次的工资调整为降薪,则此思路通不过。具体思路如下:
1、直接找到emp_no=10001的员工的工资记录,将其最大工资减去最小工资得到涨幅
SELECT (MAX(salary)-MIN(salary)) AS growth FROM salaries WHERE emp_no = '10001'

第二十题

题目描述

  • 查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序
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 A.emp_no,(A.salary-B.salary) AS growth 
FROM  
(SELECT S.emp_no,S.salary  FROM employees AS E LEFT JOIN salaries AS S ON E.emp_no =S.emp_no 
WHERE S.to_date = '9999-01-01') AS A 
INNER JOIN  
(SELECT S.emp_no,S.salary FROM employees AS E LEFT JOIN salaries AS S ON S.emp_no = E.emp_no 
WHERE S.from_date = E.hire_date) AS B 
ON A.emp_no = B.emp_no 
ORDER BY growth ASC;


思路如下:
1.找出每个员工当前工资 作为A
S.to_date = '9999-01-01'为当前工资
2.找出每个员工入职时的工资作为表B
S.from_date = E.hire_date)为入职时工资
3.结合找出增长
通过 A.emp_no = B.emp_no,把AB两表关联,薪资相减