MySQL_04SQL子查询

MySQL_04SQL子查询

1.什么是子查询

select语句中嵌套select语句,被嵌套的select语句被称为子查询

2.在什么地方可以使用子查询

  • select..(select)
  • from...(select)
  • where(select)

3.在where后面使用

3.1案例

  • 找出比最低工资高的员工姓名和工资

3.2实现

  • 第一步

    • 查询出最低工资

      mysql> select min(sal) from emp;
      +----------+
      | min(sal) |
      +----------+
      |   800.00 |
      +----------+
      1 row in set (0.01 sec)
      
  • 第二步

    • 找出大于800的员工姓名和工资

      mysql> select ename,sal from emp where sal > 800;
      +--------+---------+
      | ename  | sal     |
      +--------+---------+
      | ALLEN  | 1600.00 |
      | WARD   | 1250.00 |
      | JONES  | 2975.00 |
      | MARTIN | 1250.00 |
      | BLAKE  | 2850.00 |
      | CLARK  | 2450.00 |
      | SCOTT  | 3000.00 |
      | KING   | 5000.00 |
      | TURNER | 1500.00 |
      | ADAMS  | 1100.00 |
      | JAMES  |  950.00 |
      | FORD   | 3000.00 |
      | MILLER | 1300.00 |
      +--------+---------+
      13 rows in set (0.01 sec)
      
  • 第三步

    • 合并

      mysql> select ename,sal from emp where sal > (select min(sal) from emp);
      +--------+---------+
      | ename  | sal     |
      +--------+---------+
      | ALLEN  | 1600.00 |
      | WARD   | 1250.00 |
      | JONES  | 2975.00 |
      | MARTIN | 1250.00 |
      | BLAKE  | 2850.00 |
      | CLARK  | 2450.00 |
      | SCOTT  | 3000.00 |
      | KING   | 5000.00 |
      | TURNER | 1500.00 |
      | ADAMS  | 1100.00 |
      | JAMES  |  950.00 |
      | FORD   | 3000.00 |
      | MILLER | 1300.00 |
      +--------+---------+
      13 rows in set (0.02 sec)
      

4.在from后面使用

4.1案例

  • 找出每个岗位的平均工资的薪资等级

4.2特点

  • 将子查询的结果当作一张临时表

4.3涉及到的表

  • emp表

    +-------+--------+-----------+------+------------+---------+---------+--------+
    | EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
    +-------+--------+-----------+------+------------+---------+---------+--------+
    |  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
    |  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
    |  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
    |  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
    |  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
    |  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
    |  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
    |  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
    |  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
    |  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
    |  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
    |  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
    |  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
    |  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
    +-------+--------+-----------+------+------------+---------+---------+--------+
    14 rows in set (0.00 sec)
    
  • salgrade表

    +-------+-------+-------+
    | GRADE | LOSAL | HISAL |
    +-------+-------+-------+
    |     1 |   700 |  1200 |
    |     2 |  1201 |  1400 |
    |     3 |  1401 |  2000 |
    |     4 |  2001 |  3000 |
    |     5 |  3001 |  9999 |
    +-------+-------+-------+
    5 rows in set (0.05 sec)
    

4.4实现

  • 第一步

    • 找出每个岗位的平均工资

      mysql> select job,avg(sal) from emp group by job;
      +-----------+-------------+
      | job       | avg(sal)    |
      +-----------+-------------+
      | ANALYST   | 3000.000000 |
      | CLERK     | 1037.500000 |
      | MANAGER   | 2758.333333 |
      | PRESIDENT | 5000.000000 |
      | SALESMAN  | 1400.000000 |
      +-----------+-------------+
      5 rows in set (0.01 sec)
      
  • 第二步

    • 把第一步查询的结果当作一张临时表t,将临时表t和salgrade表进行表连接

      mysql> select t.*,s.grade
        -> from (select job,avg(sal) as avgsal from emp group by job) as t
        -> join salgrade as s
        -> on t.avgsal between s.losal and s.hisal;
      +-----------+-------------+-------+
      | job    | avgsal   | grade |
      +-----------+-------------+-------+
      | CLERK   | 1037.500000 |   1 |
      | SALESMAN | 1400.000000 |   2 |
      | ANALYST  | 3000.000000 |   4 |
      | MANAGER  | 2758.333333 |   4 |
      | PRESIDENT | 5000.000000 |   5 |
      +-----------+-------------+-------+
      5 rows in set (0.01 sec)
      

5.在select后面使用

5.1案例

  • 找出每个员工的部门名称,要求显示员工名、部门名

5.2涉及到的表

  • emp表

    +-------+--------+-----------+------+------------+---------+---------+--------+
    | EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
    +-------+--------+-----------+------+------------+---------+---------+--------+
    |  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
    |  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
    |  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
    |  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
    |  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
    |  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
    |  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
    |  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
    |  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
    |  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
    |  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
    |  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
    |  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
    |  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
    +-------+--------+-----------+------+------------+---------+---------+--------+
    14 rows in set (0.00 sec)
    
  • dept表

    +--------+------------+----------+
    | DEPTNO | DNAME      | LOC      |
    +--------+------------+----------+
    |     10 | ACCOUNTING | NEW YORK |
    |     20 | RESEARCH   | DALLAS   |
    |     30 | SALES      | CHICAGO  |
    |     40 | OPERATIONS | BOSTON   |
    +--------+------------+----------+
    4 rows in set (0.01 sec)
    

5.3实现

  • 在select后面完成dname的查询

    mysql> select e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname
        -> from emp e;
    +--------+------------+
    | ename  | dname      |
    +--------+------------+
    | SMITH  | RESEARCH   |
    | ALLEN  | SALES      |
    | WARD   | SALES      |
    | JONES  | RESEARCH   |
    | MARTIN | SALES      |
    | BLAKE  | SALES      |
    | CLARK  | ACCOUNTING |
    | SCOTT  | RESEARCH   |
    | KING   | ACCOUNTING |
    | TURNER | SALES      |
    | ADAMS  | RESEARCH   |
    | JAMES  | SALES      |
    | FORD   | RESEARCH   |
    | MILLER | ACCOUNTING |
    +--------+------------+
    14 rows in set (0.00 sec)
    

5.4注意

  • 在select后面的子查询结果一次不能超过一个,不然就报错

    mysql> select e.ename,(select d.dname from dept d) as dname from emp e;
    ERROR 1242 (21000): Subquery returns more than 1 row
    
上一篇:子查询、union、表复制


下一篇:Oracle 数据采样