版权声明:YETA https://blog.csdn.net/qq_28958301/article/details/89088488
本篇博客用于记录在牛客网做的数据库SQL实战中的错题或重要的题。
- 查找最晚入职员工的所有信息
SELECT
*
FROM
employees
WHERE
hire_date = (
SELECT
MAX(hire_date)
FROM
employees
);
- 查找入职员工时间排名倒数第三的员工所有信息
SELECT
*
FROM
employees
WHERE
hire_date = (
SELECT DISTINCT
hire_date
FROM
employees
ORDER BY
hire_date DESC
LIMIT 2,
1
);
- 查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号dept_no
SELECT
s.*, dm.dept_no
FROM
salaries AS s
INNER JOIN dept_manager AS dm ON dm.emp_no = s.emp_no
WHERE
s.to_date = '9999-01-01'
AND dm.to_date = '9999-01-01';
- 查找所有已经分配部门的员工的last_name和first_name
SELECT
e.last_name,
e.first_name,
de.dept_no
FROM
employees AS e
INNER JOIN dept_emp AS de ON de.emp_no = e.emp_no;
- 查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括展示没有分配具体部门的员工
SELECT
e.last_name,
e.first_name,
de.dept_no
FROM
employees AS e
LEFT JOIN dept_emp AS de ON de.emp_no = e.emp_no;
- 查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序
SELECT
s.emp_no,
s.salary
FROM
employees AS e
INNER JOIN salaries AS s ON s.emp_no = e.emp_no
WHERE
e.hire_date = s.from_date
ORDER BY
e.emp_no DESC;
- 查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t
SELECT
temp.emp_no,
temp.t
FROM
(
SELECT
emp_no,
COUNT(salary) AS t
FROM
salaries
GROUP BY
emp_no
) AS temp
WHERE
temp.t > 15;
- 找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
SELECT DISTINCT
salary
FROM
salaries
WHERE
to_date = '9999-01-01'
ORDER BY
salary DESC;
SELECT
salary
FROM
salaries
WHERE
to_date = '9999-01-01'
GROUP BY
salary
ORDER BY
salary DESC;
- 获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary,当前表示to_date='9999-01-01'
SELECT
dm.dept_no,
dm.emp_no,
s.salary
FROM
dept_manager AS dm
INNER JOIN salaries AS s ON s.emp_no = dm.emp_no
WHERE
dm.to_date = '9999-01-01'
AND s.to_date = '9999-01-01';
- 获取所有非manager的员工emp_no
SELECT
emp_no
FROM
employees
WHERE
emp_no NOT IN (
SELECT
emp_no
FROM
dept_manager
);
SELECT
e.emp_no
FROM
employees AS e
LEFT JOIN dept_manager AS dm ON dm.emp_no = e.emp_no
WHERE
dm.dept_no IS NULL;
- 获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date='9999-01-01'。
结果第一列给出当前员工的emp_no,第二列给出其manager对应的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
de.to_date = '9999-01-01'
AND dm.to_date = '9999-01-01'
AND de.emp_no != dm.emp_no;
- 获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
SELECT
de.dept_no,
de.emp_no,
MAX(s.salary) AS salary
FROM
dept_emp AS de
INNER JOIN salaries AS s ON de.emp_no = s.emp_no
WHERE
de.to_date = '9999-01-01'
AND s.to_date = '9999-01-01'
GROUP BY
de.dept_no;
- 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
SELECT
title,
count(0) AS t
FROM
titles
GROUP BY
title
HAVING
t >= 2;
- 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t,注意对于重复的emp_no进行忽略。
SELECT
title,
count(DISTINCT emp_no) AS t
FROM
titles
GROUP BY
title
HAVING
t >= 2;
- 查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
SELECT
*
FROM
employees
WHERE
emp_no % 2 != 0
AND last_name != 'Mary'
ORDER BY
hire_date DESC;
- 统计出当前各个title类型对应的员工当前薪水对应的平均工资。结果给出title以及平均工资avg。
SELECT
title,
AVG(s.salary) AS avg
FROM
titles AS t
INNER JOIN salaries AS s ON t.emp_no = s.emp_no
WHERE
t.to_date = '9999-01-01'
AND s.to_date = '9999-01-01'
GROUP BY
t.title;
- 获取当前(to_date='9999-01-01')薪水第二多的员工的emp_no以及其对应的薪水salary
SELECT
s.emp_no,
s.salary
FROM
salaries AS s
INNER JOIN (
SELECT
salary
FROM
salaries
WHERE
to_date = '9999-01-01'
GROUP BY
salary
ORDER BY
salary DESC
LIMIT 1,
1
) AS temp ON temp.salary = s.salary;
- 查找当前薪水(to_date='9999-01-01')排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
SELECT
s.emp_no,
s.salary,
e.last_name,
e.first_name
FROM
salaries AS s
INNER JOIN employees AS e ON s.emp_no = e.emp_no
WHERE
s.salary = (
SELECT
max(salary)
FROM
salaries
WHERE
salary != (
SELECT
max(salary)
FROM
salaries
WHERE
salary
)
);
- 查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
SELECT
e.last_name,
e.first_name,
d.dept_name
FROM
employees AS e
LEFT JOIN dept_emp AS de ON e.emp_no = de.emp_no
LEFT JOIN departments AS d ON de.dept_no = d.dept_no;
- 查找员工编号emp_no为10001其自入职以来的薪水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
- 查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序
SELECT
temp1.emp_no,
temp1.salary - temp2.salary AS growth
FROM
(
SELECT
e.emp_no,
s.salary
FROM
employees AS e
INNER JOIN salaries AS s ON (
e.emp_no = s.emp_no
AND s.to_date = '9999-01-01'
)
) AS temp1,
(
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
)
) AS temp2
WHERE
temp1.emp_no = temp2.emp_no
ORDER BY
growth ASC;
- 统计各个部门对应员工涨幅的次数总和,给出部门编码dept_no、部门名称dept_name以及次数sum
SELECT
d.dept_no,
dept.dept_name,
count(salary)
FROM
salaries s,
dept_emp d,
departments dept
WHERE
s.emp_no = d.emp_no
AND d.dept_no = dept.dept_no
GROUP BY
dept.dept_no;
- 对所有员工的当前(to_date='9999-01-01')薪水按照salary进行按照1-N的排名,相同salary并列且按照emp_no升序排列
SELECT
s1.emp_no,
s1.salary,
(
SELECT
count(DISTINCT s.salary)
FROM
salaries AS s
WHERE
s.to_date = '9999-01-01'
AND s.salary >= s1.salary
) AS rank
FROM
salaries AS s1
WHERE
s1.to_date = '9999-01-01'
ORDER BY
s1.salary DESC,
s1.emp_no ASC;
SELECT
s1.emp_no,
s1.salary,
COUNT(DISTINCT s2.salary) AS rank
FROM
salaries AS s1
INNER JOIN salaries AS s2 ON s1.to_date = '9999-01-01'
AND s2.to_date = '9999-01-01'
AND s1.salary <= s2.salary
GROUP BY
s1.emp_no
ORDER BY
rank ASC,
s1.emp_no ASC;
- 获取所有非manager员工当前的薪水情况,给出dept_no、emp_no以及salary ,当前表示to_date='9999-01-01'
SELECT
de.dept_no,
e.emp_no,
s.salary
FROM
employees AS e
LEFT JOIN dept_manager AS dm ON dm.emp_no = e.emp_no
INNER JOIN dept_emp AS de ON de.emp_no = e.emp_no
INNER JOIN salaries AS s ON s.emp_no = e.emp_no
WHERE
dm.dept_no IS NULL
AND s.to_date = '9999-01-01';
- 获取员工其当前的薪水比其manager当前薪水还高的相关信息,当前表示to_date='9999-01-01'
SELECT
s.emp_no,
dm2.emp_no AS manager_no,
s.salary AS emp_salary,
s2.salary AS manager_salary
FROM
salaries AS s
LEFT JOIN dept_manager AS dm ON dm.emp_no = s.emp_no
INNER JOIN dept_emp AS de ON de.emp_no = s.emp_no
INNER JOIN dept_manager AS dm2 ON dm2.dept_no = de.dept_no
INNER JOIN salaries AS s2 ON s2.emp_no = dm2.emp_no
WHERE
dm.dept_no IS NULL
AND s.to_date = '9999-01-01'
AND s2.to_date = '9999-01-01'
AND s.salary > s2.salary;
- 汇总各个部门当前员工的title类型的分配数目,结果给出部门编号dept_no、dept_name、其当前员工所有的title以及该类型title对应的数目count
SELECT
d.dept_no,
d.dept_name,
t.title,
COUNT(t.title) AS count
FROM
titles AS t
INNER JOIN dept_emp AS de ON de.emp_no = t.emp_no
INNER JOIN departments AS d ON d.dept_no = de.dept_no
WHERE
de.to_date = '9999-01-01'
AND t.to_date = '9999-01-01'
GROUP BY
d.dept_no,
t.title;
- 给出每个员工每年薪水涨幅超过5000的员工编号emp_no、薪水变更开始日期from_date以及薪水涨幅值salary_growth,并按照salary_growth逆序排列
SELECT
s2.emp_no,
s2.from_date,
(s2.salary - s1.salary) AS salary_growth
FROM
salaries AS s1,
salaries AS s2
WHERE
s1.emp_no = s2.emp_no
AND s2.salary - s1.salary > 5000
AND YEAR (s2.to_date) - YEAR (s1.to_date) = 1
ORDER BY
salary_growth DESC;