[Cattle off the database SQL combat] 11 to 20 personal questions and answers

11. Get all the current staff of the manager, if the current manager is not in their own words the results show that the current representation to_date = '9999-01-01'.

The results are given in the first column of the current emp_no employees, which gives the manager the second column corresponding manager_no

-- dept_emp部门员工表找到员工emp_no对应的部门dept_no, dept_manager部门管理表再找到管理者emp_no
SELECT de.emp_no, dm.emp_no AS manager_no 
FROM dept_emp AS de, dept_manager AS dm 
WHERE de.emp_no!=dm.emp_no AND dm.dept_no=de.dept_no 
AND de.to_date="9999-01-01" AND dm.to_date="9999-01-01";

Running time: 30ms

Take up memory: 3464k

-- 使用内连接INNER JOIN关联部门员工表和管理员表
SELECT de.emp_no, dm.emp_no AS manager_no 
FROM dept_emp AS de 
INNER JOIN dept_manager AS dm 
ON dm.dept_no=de.dept_no 
WHERE de.emp_no!=dm.emp_no 
AND de.to_date="9999-01-01" AND dm.to_date="9999-01-01";

Running time: 16ms

Take up memory: 3344k

12. Get all departments in the current highest-paid employee information, given dept_no, emp_no and their corresponding salary

Current (to_date = "9999-01-01") each department 's highest paid employees
Note: The title and auditing systems are pit ...

SELECT re1.dept_no, re2.emp_no, re1.salary
FROM (
    -- 先找出各部门最高薪水值 通过部门编号分组
    SELECT dept_em.dept_no, MAX(em_sa.salary) AS salary
    FROM (
        SELECT emp_no, salary
        FROM salaries
        WHERE to_date = '9999-01-01'
    ) AS em_sa
    LEFT JOIN (
        SELECT emp_no, dept_no
        FROM dept_emp
        WHERE to_date = '9999-01-01'
    ) AS dept_em 
    ON em_sa.emp_no = dept_em.emp_no
    GROUP BY dept_no) re1
JOIN (
    -- 再找出各部门员工的薪水值 通过左连接
    SELECT dept_em.dept_no, em_sa.emp_no, em_sa.salary AS salary
    FROM (
        SELECT emp_no, salary
        FROM salaries
        WHERE to_date = '9999-01-01'
    ) AS em_sa
    LEFT JOIN (
        SELECT emp_no, dept_no
        FROM dept_emp
        WHERE to_date = '9999-01-01'
    ) AS dept_em 
    ON em_sa.emp_no = dept_em.emp_no) re2 
-- 通过连接获得最高薪水值对应的员工编号
ON re1.dept_no = re2.dept_no AND re1.salary = re2.salary
ORDER BY re1.dept_no;

Running time: 20ms

Take up memory: 5076k

  • SQL code analysis:
    The first solution: 6.67's
-- 通过to_date缩减需要选取的数据 
-- 当前salaries表的emp_no和salary 
SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01';
-- 当前dept_emp表的dept_no和emp_no
SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01';
-- 通过部门编号分组, 当前各部门的最高薪水salary和部门编号dept_no
SELECT dm.dept_no, MAX(se.salary) salary
FROM (
    (
        SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01'
    ) AS se
    LEFT JOIN
    (
        SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01'
    ) AS dm
    ON se.emp_no=dm.emp_no)
GROUP BY dm.dept_no;
-- 无需分组, 将部门/员工/薪水合并到一个表内
SELECT dm.dept_no, dm.emp_no, se.salary
FROM (
    (
        SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01'
    ) AS se
    LEFT JOIN
    (
        SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01'
    ) AS dm
    ON se.emp_no=dm.emp_no);
-- 通过`部门/最高薪水`的条件 去筛选/定位 `员工编号`
SELECT re1.dept_no, re2.emp_no, re1.salary
FROM (
    SELECT dm.dept_no, MAX(se.salary) salary
    FROM (
        (
            SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01'
        ) AS se
        LEFT JOIN
        (
            SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01'
        ) AS dm
        ON se.emp_no=dm.emp_no)
    GROUP BY dm.dept_no
) AS re1 JOIN (
    SELECT dm.dept_no, dm.emp_no, se.salary
    FROM (
        (
            SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01'
        ) AS se
        LEFT JOIN
        (
            SELECT dept_no, emp_no FROM dept_emp WHERE to_date='9999-01-01'
        ) AS dm
        ON se.emp_no=dm.emp_no)
) AS re2
ON re2.dept_no=re1.dept_no AND re2.salary=re1.salary
ORDER BY re1.dept_no;

The second solution: 5.93's result is the same, but not by cattle customer review

SELECT de.dept_no,sa.emp_no,re.sal AS salary
FROM (
    -- 通过分组,拿到各部门编号以及对应的最高薪水
    SELECT d.dept_no, MAX(s.salary) AS sal
    FROM dept_emp AS d JOIN salaries AS s
    ON 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 re, dept_emp AS de, salaries AS sa
-- 三表查询 re的最高薪水 部门员工表的部门编号 薪水表的员工编号
WHERE re.dept_no=de.dept_no AND de.emp_no=sa.emp_no AND re.sal=sa.salary;

13. titles acquired from the table are grouped by title, the number of each group is two or more, gives the title number and corresponding t

SELECT title, COUNT(title) AS t FROM titles GROUP BY title HAVING t >= 2;

Running time: 18ms

Take up memory: 3424k

  • Note: where and having difference is that, where a lookup is defined before, is to find and after having

14. Get the title titles table grouped, in groups of more than 2, and gives the corresponding title number t.

Note that for repeat emp_no be ignored

-- 统计拥有相同 title 的不同员工的个数 distinct可以放入函数体内
SELECT title, COUNT(DISTINCT emp_no) AS t FROM titles GROUP BY title HAVING t >= 2;

Running time: 17ms

Take up memory: 3300k

15. A lookup table for all employees emp_no odd and not last_name Mary's employee information and arranged in reverse hire_date

-- 判断属性奇偶数 1)取余 2)除与2再乘与2 3)位运算
SELECT * FROM employees WHERE emp_no%2=1 AND last_name!='Mary' ORDER BY hire_date DESC;

Running time: 20ms

Take up memory: 3400k

Analyzing mysql odd and even, and Reflection Efficiency

16. The current statistics of each title corresponding to the type of the current staff salary corresponding to the average wage. The results are given title, and the average wage avg.

-- 注意avg是sql语法的关键字,需要``对其进行标注
SELECT t.title, AVG(s.salary) AS `avg` FROM titles AS t INNER JOIN salaries AS s ON s.emp_no=t.emp_no AND s.to_date='9999-01-01' AND t.to_date='9999-01-01' GROUP BY title;

Running time: 28ms

Take up memory: 3404k

17. Get the current second-emp_no (to_date = '9999-01-01') and its corresponding salary employees salary salary

-- 将salaries表按薪水salary逆序排列,再选取第二位
SELECT emp_no, salary FROM salaries WHERE to_date='9999-01-01' ORDER BY salary DESC LIMIT 1,1;

Running time: 22ms

Take up memory: 3320k

-- 以上方法是有缺陷的,题意是指薪水第二多,而同一薪水可能有多名员工
-- 先求出当前第二多薪水数额(distinct和group by都可以)
SELECT DISTINCT salary FROM salaries WHERE to_date='9999-01-01' ORDER BY salary DESC LIMIT 1,1;
SELECT salary FROM salaries WHERE to_date='9999-01-01' GROUP BY salary ORDER BY salary DESC LIMIT 1,1;
-- 再通过当前时间和薪水数额定位员工编号
SELECT emp_no, salary FROM salaries WHERE salary = (
    SELECT DISTINCT salary FROM salaries WHERE to_date='9999-01-01' ORDER BY salary DESC LIMIT 1,1
) AND to_date='9999-01-01';

Running time: 22ms

Take up memory: 3552k

18. Find the current salary (to_date = '9999-01-01') ranked second and more employees number emp_no, salary salary, last_name and first_name, are not allowed to use order by

-- 先找出当前最多薪水数额
SELECT MAX(salary) FROM salaries WHERE to_date='9999-01-01';
-- 使用排除法,在去掉最大值的序列中,此时最大值就原序列的第二大值
SELECT MAX(salary) FROM salaries 
WHERE to_date='9999-01-01' AND salary NOT IN (
    SELECT MAX(salary)  FROM salaries WHERE to_date='9999-01-01'
);
-- 使用以上求取得到的第二大值
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.to_date='9999-01-01'
AND s.salary = (
    SELECT MAX(salary) FROM salaries 
    WHERE to_date='9999-01-01' AND salary NOT IN (
        SELECT MAX(salary)  FROM salaries WHERE to_date='9999-01-01'
    )
);

Running time: 24ms

Take up memory: 3304k

19. Find last_name and first_name and corresponding dept_name all employees, including temporary employees are not assigned sector

-- 先将员工表employees和部门员工表dept_emp连接 合成部门员工详细表ds
SELECT e.emp_no, de.dept_no FROM employees AS e LEFT JOIN dept_emp AS de ON e.emp_no=de.emp_no;
-- 再将部门信息表department和部门员工详细表ds连接
SELECT ds.last_name, ds.first_name, d.dept_name FROM (
    SELECT e.last_name, e.first_name, de.dept_no FROM employees AS e LEFT JOIN dept_emp AS de ON e.emp_no=de.emp_no
) AS ds LEFT JOIN departments AS d ON d.dept_no=ds.dept_no;

Running time: 18ms

Take up memory: 3312k

-- 第一次 left join 是把未分配部门的员工算进去了,但是只得到了部门编号dept_no,没有部门名dept_name,
-- 所以第二次也要 left join 把含有部门名 departments表 连接起来,
-- 否则在第二次连接时就选不上未分配部门的员工了
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;

Running time: 20ms

Take up memory: 3404k

20. Find emp_no employee number 10001 from their salary salary increase since the entry value growth

Personal understanding is: increase the distance the latest wage salary at the time of obtaining entry

-- 最大值-最小值 这种解法是有问题的 其是以薪水一直在涨/上升的前提下
SELECT (MAX(salary)-MIN(salary)) AS growth FROM salaries WHERE emp_no='10001';

Running time: 19ms

Take up memory: 3424k

-- 薪水salary涨幅值growth 当前薪水-入职薪水
SELECT (ma.salary-mi.salary) AS growth
FROM (
        -- 入职薪水
    SELECT salary FROM salaries WHERE emp_no='10001' ORDER BY to_date LIMIT 0,1
) AS mi, (
        -- 当前薪水
    SELECT salary FROM salaries WHERE emp_no='10001' ORDER BY to_date DESC LIMIT 0,1
) AS ma;

Running time: 21ms

Take up memory: 3688k

Complete personal practice code for

I practice SQL code has been uploaded to Github: https://github.com/slowbirdoflsh/newcode-sql-practice
for reference only ~ ~ ~

Guess you like

Origin www.cnblogs.com/slowbirdoflsh/p/11210684.html