MySQL学习-相关子查询(二)

106 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

前言

上篇我们学习了一部分MySQL子查询中的相关子查询。有兴趣的小伙伴可以阅读(# MySQL学习-相关子查询(一))。
下面继续学习MySQL子查询中的相关子查询。

相关子查询

上一节中关于相关子查询有个结论:
在SELECT中,除了GROUP BY和LIMIT之外,其他位置都可以声明子查询。
下面继续用例子来说明。

举例一

若employees表中的employee_id与job_history表中的employee_id相同的数目不小于2,查询这些相同id的员工的employee_id,name和其job_id。
这里是查询员工调岗过2次以上部门的员工信息。

SELECT employee_id, name, job_id
FROM employees e
WHERE 2 <= (
            SELECT COUNT(*)
            FROM job_history j
            WHERE e.'employee_id' = j.'employee_id'
            );

这样就可以查出调岗2次以上的员工信息。

EXISTS与NOT EXISTS关键字

  • 关联子查询通常也会和EXISTS操作符一起来使用,用来检查在子查询中是否存在满足条件的行。
  • 如果在子查询中不存在满足条件的行:
    • 条件返回FALSE
    • 继续在子查询中查找
  • 如果在子查询中存在满足条件的行:
    • 不在子查询中查找
    • 条件返回TRUE
  • NOT EXISTS关键字表示如果不存在某种条件,则返回TRUE,否则返回FALSE。

举例二

查询公司管理者的employee_id, name, job_id, department_id信息。

方式一: 自连接

SELECT DISTINCT employee_id, name, job_id, department_id
FROM employees emp JOIN employees mgr
ON emp.manager_id = mgr.manager_id

使用自连接就可以查出结果。

方式二: 子查询 子查询中先查出管理者的id,再用管理者的id去查该管理者的信息。

SELECT employee_id, name, job_id, department_id
FROM employees
WHERE employee_id IN (
                        SELECT DISTINCT manager_id
                        FROM employees
                        );

使用子查询的方式也可以查出结果。

方式三: 使用EXISTS

SELECT employee_id, name, job_id, department_id
FROM employees e1
WHERE EXISTS (
                SELECT *
                FROM employees e2
                WHERE e1.'employee_id' = e2.'manager_id'
                );

这里使用EXISTS也可以查出结果。这里的意思是,先从外查询中查找一条记录,传入子查询中,子查询循环查找是否符合条件,符合返回TRUE,不再循环,不符合返回FALSE,继续查询。

举例三

查询departments表中,不存在与employees表中部门的department_id和department_name。

方式一 使用外连接

SELECT d.department_id, d.department_name
FROM employees e RIGHT JOIN departments d
ON e.'department_id' = d.'department_id'
WHERE e.'department_id' IS NULL

使用右外连接的方式,可以查出想要的结果。

方式二 使用EXISTS

SELECT department_id, department_name
FROM departments d
WHERE EXISTS (
                SELECT *
                FROM employees e
                WHERE d.'department_id' = e.'department_id'
                );

使用EXISTS查出结果。

今天先学习到这里,明天继续。