zoukankan      html  css  js  c++  java
  • 数据库MySQL--子查询

    例子文件1:https://files.cnblogs.com/files/Vera-y/myemployees.zip

    子查询:又称内查询,出现在其他语句中的select语句

    主查询:又称外查询,内部嵌套其他select语句的查询

    分类:

    按结果集的行列数不同:

      标量(单行)子查询:结果集只有一行一列

      列(多行)子查询:结果集只有一列多行

      行子查询:结果集有一行多列

      表子查询:结果集一般为多行多列(也可包含一行多列等)

    按子查询出现的位置:

      select 后面:仅仅支持标量子查询

      from 后面:支持表子查询

      ♦ where或having后面:支持标量子查询、列子查询、(也可行子查询(使用较少))

      exists后面(又称相关子查询):表子查询

    一、放在where或having后面

    特点:1)子查询语句放在小括号内

       2)子查询语句一般放在条件的右侧

       3)标量子查询,一般配合这单行操作符使用(> < >= <= = <>)

          列子查询,一般搭配多行操作符使用(IN / NOT IN 、ANY / SOME 、ALL)

       4)子查询的执行优先于主查询的执行

    非法使用标量子查询:

      1)子查询结果集不为一行一列

      2)子查询结果集为空

    1.标量子查询

    例1.谁的工资比Abel高?

    SELECT last_name,salary
    FROM employees
    WHERE salary>(
    SELECT salary
    FROM employees
    WHERE last_name='Abel'
    );

    例2.返回job_id与141号员工相同,salary比143员工多的员工 姓名,job_id和工资

    SELECT salary,last_name,job_id
    FROM employees
    WHERE salary > (
    SELECT salary
    FROM employees
    WHERE employee_id='143'
    )AND job_id = (
    SELECT job_id
    FROM employees
    WHERE employee_id='141'
    );

    例3.查询最低工资大于50号部门最低工资的部门id和其最低工资

    SELECT department_id,MIN(salary)
    FROM employees
    GROUP BY department_id
    HAVING MIN(salary) > (
    SELECT MIN(salary)
    FROM employees
    WHERE department_id=50
    );

    2.列子查询(单列多行子查询)

    例1.返回location_id 是1400或1700的部门中所有员工姓名

    SELECT last_name
    FROM employees
    WHERE department_id IN(        # 这里的 IN 可以替换外 =ANY
    SELECT DISTINCT department_id
    FROM departments
    WHERE location_id IN(1400,1700)
    );

    例2.返回其它工种中比job_id为 IT_PROG工种任一工资低的员工的员工号、姓名、job_id、salary

    SELECT employee_id, last_name,job_id,salary
    FROM employees
    WHERE salary<ANY(
    SELECT DISTINCT salary # 去重
    FROM employees
    WHERE job_id = 'IT_PROG'
    )AND job_id <> 'IT_PROG';
    # 或
    SELECT employee_id, last_name,job_id,salary
    FROM employees
    WHERE salary<(
    SELECT MAX(salary)
    FROM employees
    WHERE job_id = 'IT_PROG'
    )AND job_id <> 'IT_PROG';

    例3.返回其它工种中比job_id为 IT_PROG工种所有工资低的员工的员工号、姓名、job_id、salary

    SELECT employee_id, last_name,job_id,salary
    FROM employees
    WHERE salary<ALL(
    SELECT DISTINCT salary # 去重
    FROM employees
    WHERE job_id = 'IT_PROG'
    )AND job_id <> 'IT_PROG';
    #或
    SELECT employee_id, last_name,job_id,salary
    FROM employees
    WHERE salary<(
    SELECT MIN(salary) # 去重
    FROM employees
    WHERE job_id = 'IT_PROG'
    )AND job_id <> 'IT_PROG';

    3.行子查询(结果集一行多列或多行多列)

    例:查询员工编号最小并且工资最高的员工信息

    1)普通解法  

      SELECT *
      FROM employees
      WHERE employee_id =(
      SELECT MIN(employee_id)
      FROM employees
      )AND salary=(
      SELECT MAX(salary)
      FROM employees
      );

    2)行子查询解法

      SELECT *
      FROM employees
      WHERE (employee_id,salary)=(
      SELECT MIN(employee_id),MAX(salary)
      FROM employees
      );

    二、放在select后面

    例1.查询每个部门的员工个数     # 部门表 、员工表

    SELECT departments.*, (
      SELECT COUNT(*)
      FROM employees
      WHERE employees.department_id = departments.department_id
    ) AS 个数
    FROM departments;

    例2.查询员工号=102的部门名    # 可直接用连接查询、标量查询等

    SELECT (                            # 只能是一行一列(标量子查询)
      SELECT department_name
      FROM departments
      INNER JOIN employees
      ON departments.department_id=employees.department_id
      WHERE employees.employee_id=102
    ) AS 部门名;

    三、放在from后面

    例、查询每个部门的平均工资的工资等级

    SELECT ag_dep.*,grade_level
    FROM(
      SELECT AVG(salary) AS ag,department_id
      FROM employees
      GROUP BY department_id
    ) AS ag_dep     # 子查询结果为一张表,注意一定要起别名
    INNER JOIN job_grades
    ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;

    四、放在exists后面(相关子查询)

    语法:select.. exists(完整的子查询语句)

    判断子查询的结果有没有值,若有值则返回布尔值1,没有则返回布尔值0

    注:exists是先执行外查询,再进行子查询的过滤

    例1.查询有员工的部门名

    用exists进行相关查询

      SELECT department_name
      FROM departments
      WHERE EXISTS(
        SELECT *
        FROM employees
        WHERE departments.department_id=employees.department_id
      );

    用IN 进行查询

      SELECT department_name
      FROM departments
      WHERE departments.department_id IN(
        SELECT department_id
        FROM employees
      );

  • 相关阅读:
    某开源ERP最新版SQL与RCE的审计过程
    QEMU固件模拟技术-stm32仿真分析及IRQ仿真实践
    QEMU固件模拟技术分析-luaqemu实现分析
    C/C++源码扫描系列- Fortify 篇
    C/C++源码扫描系列- Joern 篇
    C/C++源码扫描系列- codeql 篇
    bluetooth_stack开源蓝牙协议栈源码分析与漏洞挖掘
    DA14531芯片固件逆向系列(4)- L2CAP及ATT层收包再分析
    DA14531芯片固件逆向系列(3)- BLE收包流程分析及漏洞挖掘思路分享
    微服务架构简单搭建——Spring Cloud Eureka、Ribbon实现服务治理与服务消费
  • 原文地址:https://www.cnblogs.com/Vera-y/p/10945502.html
Copyright © 2011-2022 走看看