[データベースのSQL戦闘オフ牛] 11〜20の個人的な質問と回答

ディレクトリ

現在のマネージャは、結果が現在の表現のTO_DATE =「9999-01-01」ことを示して自分の言葉ではない場合11.、管理者の現在のすべてのスタッフを取得します。

結果をマネージャにmanager_noに対応する第二の列を与える現在のEMP_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";

30ミリ秒:時間を実行します

メモリを取る: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";

実行時間:16msのを

メモリを取る:3344kを

12. DEPT_NO、EMP_NOとそれに対応する給料与え​​られ、現在の最高給従業員情報内のすべての部門を取得します

現在(TO_DATE =「9999-01-01」)各部門の最高の有給従業員が
注意:タイトルと監査システムは、ピットです...

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;

実行時間:20msのを

メモリを取る:5076kを

  • SQLコード解析:
    第一溶液:6.67さん
-- 通过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;

第二の溶液:5.93の結果は同じですが、ない牛のカスタマーレビューにより、

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タイトルがタイトル別にグループ化され、各グループの数が2以上である、タイトル番号と対応するTを与え

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

18ms:実行時間

メモリを取る:3424kを

  • 注意:どこで差がルックアップが前に定義されているたところ、ことを、見つけることであるとした後

14. 2つ以上のグループには、グループ化されたタイトルのタイトルテーブルを取得し、対応するタイトル番号tを与えます。

リピートEMP_NOのために無視されることに注意してください

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

17ms:実行時間

メモリを取る:3300Kを

すべての従業員のための15のルックアップテーブルは、奇数EMP_NOとメアリーの従業員情報をLAST_NAME、逆入社年月日に配置されていません

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

実行時間:20msのを

メモリを取る:3400Kを

分析mysqlの奇数と偶数、及び反射効率

平均賃金に相当する現在の職員の給与の種類に対応した各タイトルの16現在の統計。結果は、タイトル、および平均賃金の平均を与えています。

-- 注意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;

28ms:実行時間

メモリを取る:3404kを

17.現在の二EMP_NO(TO_DATE =「9999-01-01」)とそれに対応する給与従業員の給与の給与を取得します

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

22msで:実行時間

メモリを取る: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';

22msで:実行時間

メモリを取る:3552kを

18.現在の給与(TO_DATE =「9999-01-01」)は第二位とより多くの従業員番号EMP_NO、給与給与、LAST_NAMEとFIRST_NAMEは、順を使用することが許可されていない検索します

-- 先找出当前最多薪水数额
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'
    )
);

24ms:実行時間

メモリを取る:3304kを

19.検索LAST_NAMEとFIRST_NAMEと対応DEPT_NAME派遣社員を含む全従業員は、部門が割り当てられていません

-- 先将员工表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;

18ms:実行時間

メモリを取る: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;

実行時間:20msのを

メモリを取る:3404kを

20.エントリ値の成長以来の給与の昇給からEMP_NO従業員番号10001を探します

個人的な理解がある:エントリの取得時の距離最新の賃金給与を増やします

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

19ms:実行時間

メモリを取る: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;

21ms:実行時間

メモリを取る:3688kを

以下のための完全な個人練習コード

私は、SQLコードはGitHubのにアップロードされた練習:https://github.com/slowbirdoflsh/newcode-sql-practice
あくまで参考です~~~

おすすめ

転載: www.cnblogs.com/slowbirdoflsh/p/11210684.html