https://www.nowcoder.com/activity/oj
    第一题:有employees表
    牛客刷题SQL - 图1
    查找employees里最晚入职员工的所有信息
    牛客刷题SQL - 图2
    最晚入职的当天未必就一个人,也许有多人,使用排序并限制得只能取得指定数量的结果

    1. SELECT * FROM employees WHERE hire_date = (SELECT max(hire_date) FROM employees)

    第二题:查找employees里入职员工时间排名倒数第三的员工所有信息
    牛客刷题SQL - 图3

    SELECT * FROM employees
    WHERE hire_date=(
    SELECT DISTINCT hire_date FROM employees ORDER BY hire_date DESC LIMIT 2,1
    )
    

    LIMIT m,n : 表示从第m+1条开始,取n条数据;
    LIMIT n : 表示从第0条开始,取n条数据,是limit(0,n)的缩写。
    ORDER BY 关键字默认按照升序对记录进行排序。如果需要按照降序对记录进行排序,您可以使用 DESC 关键字。
    (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条件中根据子查询查出的倒数第三晚入职的日期,就能查询出符合条件的员工信息。
    ======================================================================================
    第三题
    有一个全部员工的薪水表salaries简况如下:
    牛客刷题SQL - 图4
    有一个各个部门的领导表dept_manager简况如下:
    牛客刷题SQL - 图5
    请你查找各个部门当前领导的薪水详情以及其对应部门编号dept_no,输出结果以salaries.emp_no升序排序,并且请注意输出结果里面dept_no列是最后一列,以上例子输出如下:
    牛客刷题SQL - 图6

    SELECT s.*,d.dept_no
    FROM salaries AS s
    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'
    

    注释:INNER JOIN 与 JOIN 是相同的。

    关于为什么一定要两个表格的时间都限制成规定时间(9999-01-01)呢?
    ——-因为薪水表是按年发的,而题目要查找的是当前的薪水,所以要过滤掉以前,而dept_manager是因为有领导会离职,to_date时间不一定是9999-01-01,所以要过滤过离职的领导
    ======================================================================================
    第四题
    有employees表
    牛客刷题SQL - 图7
    和dept_emp表
    牛客刷题SQL - 图8
    请你查找所有已经分配部门的员工的last_name和first_name以及dept_no,未分配的部门的员工不显示,以上例子如下:
    牛客刷题SQL - 图9

    SELECT e.last_name,e.first_name,d.dept_no
    FROM employees AS e ,dept_emp AS d
    WHERE e.emp_no = d.emp_no
    
    SELECT 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;
    

    第五题
    查找所有已经分配部门的员工的last_name和first_name以及dept_no,也包括暂时没有分配具体部门的员工,以上例子如下:
    牛客刷题SQL - 图10

    SELECT e.last_name, e.first_name, d.dept_no
    FROM employees AS e
    LEFT OUTER JOIN dept_emp AS d
    ON e.emp_no=d.emp_no;
    

    第七题
    有一个薪水表,salaries简况如下:
    牛客刷题SQL - 图11
    请你查找薪水记录超过15次的员工号emp_no以及其对应的记录次数t,以上例子输出如下:
    牛客刷题SQL - 图12

    SELECT emp_no,COUNT(emp_no) AS t FROM salaries
    GROUP BY emp_no HAVING t >15
    

    1、用COUNT()函数和GROUP BY语句可以统计同一emp_no值的记录条数
    2、根据题意,输出的变动次数为t,故用AS语句将COUNT(emp_no)的值转换为t
    3、由于COUNT()函数不可用于WHERE语句中,故使用HAVING语句来限定t>15的条件[having 是过滤组 where过滤行,你先group by 那么having之后是得到的是满足某种条件的其中某一组,]
    WHERE语句在GROUP BY语句之前,SQL会在分组之前计算WHERE语句。
    HAVING语句在GROUP BY语句之后,SQL会在分组之后计算HAVING语句。

    第八题
    有一个薪水表,salaries简况如下:
    牛客刷题SQL - 图13
    你找出所有员工具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示,以上例子输出如下:
    牛客刷题SQL - 图14

    SELECT DISTINCT salary FROM salaries
    WHERE to_date = '9999-01-01'
    ORDER BY salary DESC
    

    说明:
    对于distinct与group by的使用:
    1.当对系统的性能高并且数据量大时使用group by
    2.当对系统的性能不高时或者使用数据量少时两者借口
    3.尽量使用group by

    第十题
    员工表employees简况如下:
    牛客刷题SQL - 图15
    部门领导表dept_manager:
    牛客刷题SQL - 图16
    找出所有非部门领导的员工emp_no
    牛客刷题SQL - 图17

    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 d
    ON e.emp_no=d.emp_no
    WHERE dept_no IS NULL;
    

    第十一题:
    有一个员工表dept_emp简况如下:
    第一行表示为员工编号为10001的部门是d001部门。
    牛客刷题SQL - 图18
    有一个部门经理表dept_manager简况如下:
    第一行表示为d001部门的经理是编号为10002的员工。
    牛客刷题SQL - 图19
    获取所有的员工和员工对应的经理,如果员工本身是经理的话则不显示,以上例子如下:
    牛客刷题SQL - 图20

    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
    

    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 代替后输出
    <> 就是不等于