【MySQL】MySQL复合查询--多表查询自连接子查询 - 副本

文章目录
  • 1.基本查询回顾
  • 2.多表查询
  • 3.自连接
  • 4.子查询
    • 4.1单行子查询
    • 4.2多行子查询
    • 4.3多列子查询
    • 4.4在from子句中使用子查询
    • 4.5合并查询
      • 4.5.1 union
      • 4.5.2 union all

1.基本查询回顾

表的内容如下:

mysql> select * from emp;
+--------+--------+-----------+------+---------------------+---------+---------+--------+
| empno  | ename  | job       | mgr  | hiredate            | sal     | comm    | deptno |
+--------+--------+-----------+------+---------------------+---------+---------+--------+
| 007369 | SMITH  | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 |
| 007499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 |
| 007521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 |
| 007566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 |
| 007654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 |
| 007698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 |
| 007782 | CLARK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 |
| 007788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 |
| 007839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 |
| 007844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 |
| 007876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 |
| 007900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 |
| 007902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 |
| 007934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 |
+--------+--------+-----------+------+---------------------+---------+---------+--------+
14 rows in set (0.00 sec)mysql> select * from dept;
+--------+------------+----------+
| deptno | dname      | loc      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)mysql> select * from salgrade;
+-------+-------+-------+
| grade | losal | hisal |
+-------+-------+-------+
|     1 |   700 |  1200 |
|     2 |  1201 |  1400 |
|     3 |  1401 |  2000 |
|     4 |  2001 |  3000 |
|     5 |  3001 |  9999 |
+-------+-------+-------+
5 rows in set (0.00 sec)
  • 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J

    // 使用模糊查询
    select * from emp where (sal>500 or job=‘MANAGER’) and ename like ‘J%’;
    // 使用函数
    select * from emp where (sal>500 or job=‘MANAGER’) and substring(ename,1,1)=‘J’;
    mysql> select * from emp where (sal>500 or job=‘MANAGER’) and ename like ‘J%’;
    ±-------±------±--------±-----±--------------------±--------±-----±-------+
    | empno | ename | job | mgr | hiredate | sal | comm | deptno |
    ±-------±------±--------±-----±--------------------±--------±-----±-------+
    | 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL | 20 |
    | 007900 | JAMES | CLERK | 7698 | 1981-12-03 00:00:00 | 950.00 | NULL | 30 |
    ±-------±------±--------±-----±--------------------±--------±-----±-------+
    2 rows in set (0.00 sec)

    mysql> select * from emp where (sal>500 or job=‘MANAGER’) and substring(ename,1,1)=‘J’;
    ±-------±------±--------±-----±--------------------±--------±-----±-------+
    | empno | ename | job | mgr | hiredate | sal | comm | deptno |
    ±-------±------±--------±-----±--------------------±--------±-----±-------+
    | 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL | 20 |
    | 007900 | JAMES | CLERK | 7698 | 1981-12-03 00:00:00 | 950.00 | NULL | 30 |
    ±-------±------±--------±-----±--------------------±--------±-----±-------+
    2 rows in set (0.00 sec)

在这里插入图片描述

  • 按照部门号升序而雇员的工资降序排序

    select * from emp order by deptno asc, sal desc;
    mysql> select * from emp order by deptno asc,sal desc;
    ±-------±-------±----------±-----±--------------------±--------±--------±-------+
    | empno | ename | job | mgr | hiredate | sal | comm | deptno |
    ±-------±-------±----------±-----±--------------------±--------±--------±-------+
    | 007839 | KING | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 | NULL | 10 |
    | 007782 | CLACK | MANAGER | 7839 | 1981-06-09 00:00:00 | 2450.00 | NULL | 10 |
    | 007934 | MILLER | CLERK | 7782 | 1982-01-23 00:00:00 | 1300.00 | NULL | 10 |
    | 007788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL | 20 |
    | 007902 | FORD | ANALYST | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL | 20 |
    | 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL | 20 |
    | 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |
    | 007369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800.00 | NULL | 20 |
    | 007698 | BLAKE | MANAGER | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL | 30 |
    | 007499 | ALLEN | SALESMAN | 7698 | 1981-02-20 00:00:00 | 1600.00 | 300.00 | 30 |
    | 007844 | TURNER | SALESMAN | 7698 | 1981-09-08 00:00:00 | 1500.00 | 0.00 | 30 |
    | 007521 | WARD | SALESMAN | 7698 | 1981-02-22 00:00:00 | 1250.00 | 500.00 | 30 |
    | 007654 | MARTIN | SALESMAN | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 | 30 |
    | 007900 | JAMES | CLERK | 7698 | 1981-12-03 00:00:00 | 950.00 | NULL | 30 |
    ±-------±-------±----------±-----±--------------------±--------±--------±-------+

在这里插入图片描述

  • 使用年薪进行降序排序

    年薪等于工资*12+奖金

    需要对奖金进行判断,如果奖金为null,则奖金为0

    select ename, sal*12+ifnull(comm,0) as ‘年薪’ from emp order by 年薪 desc;

    mysql> select ename,sal*12+ifnull(comm,0) as ‘年薪’ from emp order by 年薪 desc;
    ±-------±---------+
    | ename | 年薪 |
    ±-------±---------+
    | SMITH | 9600.00 |
    | ALLEN | 19500.00 |
    | WARD | 15500.00 |
    | JONES | 35700.00 |
    | MARTIN | 16400.00 |
    | BLAKE | 34200.00 |
    | TEST | 29400.00 |
    | SCOTT | 36000.00 |
    | KING | 60000.00 |
    | TURNER | 18000.00 |
    | ADAMS | 13200.00 |
    | JAMES | 11400.00 |
    | FORD | 36000.00 |
    | MILLER | 15600.00 |
    ±-------±---------+
    14 rows in set (0.00 sec)

在这里插入图片描述

  • 显示工资最高的员工的名字和工作岗位

    这里使用分组查询即可,先查出最高的工资,然后查询工资等于最高工资的员工的姓名和工作岗位

    select ename,job from emp where sal = (select max(sal) from emp);

    mysql> select ename,job from emp where sal = (select max(sal) from emp);
    ±------±----------+
    | ename | job |
    ±------±----------+
    | KING | PRESIDENT |
    ±------±----------+
    1 row in set (0.00 sec)

在这里插入图片描述

  • 显示工资高于平均工资的员工信息

    这里使用分组查询即可

    select ename,sal from emp where sal > (select avg(sal) from emp);

    mysql> select ename,sal from emp where sal > (select avg(sal) from emp);
    ±------±--------+
    | ename | sal |
    ±------±--------+
    | JONES | 2975.00 |
    | BLAKE | 2850.00 |
    | TEST | 2450.00 |
    | SCOTT | 3000.00 |
    | KING | 5000.00 |
    | FORD | 3000.00 |
    ±------±--------+
    6 rows in set (0.00 sec)

在这里插入图片描述

  • 显示每个部门的平均工资和最高工资

    select deptno,avg(sal),max(sal) from emp group by deptno;

    mysql> select deptno,avg(sal),max(sal) from emp group by deptno;
    ±-------±------------±---------+
    | deptno | avg(sal) | max(sal) |
    ±-------±------------±---------+
    | 10 | 2425.000000 | 5000.00 |
    | 20 | 2175.000000 | 3000.00 |
    | 30 | 1690.000000 | 2850.00 |
    ±-------±------------±---------+
    3 rows in set (0.00 sec)

在这里插入图片描述

  • 显示平均工资低于2000的部门号和它的平均工资

    select deptno,avg(sal) as avg_sal from emp group by deptno having avg_sal < 2000;

    mysql> select deptno,avg(sal) as avg_sal from emp group by deptno having avg_sal < 2000;
    ±-------±------------+
    | deptno | avg_sal |
    ±-------±------------+
    | 30 | 1690.000000 |
    ±-------±------------+
    1 row in set (0.00 sec)

在这里插入图片描述

  • 显示每种岗位的雇员总数,平均工资

    select job,count(*), avg(sal) from emp group by job;

    mysql> select job,count(), avg(sal) from emp group by job;
    ±----------±---------±------------+
    | job | count(
    ) | avg(sal) |
    ±----------±---------±------------+
    | ANALYST | 2 | 3000.000000 |
    | CLERK | 4 | 1037.500000 |
    | MANAGER | 3 | 2758.333333 |
    | PRESIDENT | 1 | 5000.000000 |
    | SALESMAN | 4 | 1400.000000 |
    ±----------±---------±------------+
    5 rows in set (0.00 sec)

在这里插入图片描述

2.多表查询

实际开发中往往数据来自不同的表,所以需要多表查询。本节我们用一个简单的公司管理系统,有三张

表emp,dept,salgrade来演示如何进行多表查询。

案例:

显示雇员名、雇员工资以及所在部门的名字因为上面的数据来自emp和dept表,因此要联合查询

在这里插入图片描述

其实我们只要emp表中的deptno = dept表中的deptno字段的记录

select ename,sal,dname from emp,dept where emp.deptno=dept.deptno;
mysql> select ename,sal,dname from emp,dept where emp.deptno=dept.deptno;
+--------+---------+------------+
| ename  | sal     | dname      |
+--------+---------+------------+
| SMITH  |  800.00 | RESEARCH   |
| ALLEN  | 1600.00 | SALES      |
| WARD   | 1250.00 | SALES      |
| JONES  | 2975.00 | RESEARCH   |
| MARTIN | 1250.00 | SALES      |
| BLAKE  | 2850.00 | SALES      |
| CLACK  | 2450.00 | ACCOUNTING |
| SCOTT  | 3000.00 | RESEARCH   |
| KING   | 5000.00 | ACCOUNTING |
| TURNER | 1500.00 | SALES      |
| ADAMS  | 1100.00 | RESEARCH   |
| JAMES  |  950.00 | SALES      |
| FORD   | 3000.00 | RESEARCH   |
| MILLER | 1300.00 | ACCOUNTING |
+--------+---------+------------+
14 rows in set (0.00 sec)

在这里插入图片描述

  • 显示部门号为10的部门名,员工名和工资

    mysql> select dname,ename,sal from emp,dept where emp.deptno=dept.deptno and dept.deptno=10;
    ±-----------±-------±--------+
    | dname | ename | sal |
    ±-----------±-------±--------+
    | ACCOUNTING | CLACK | 2450.00 |
    | ACCOUNTING | KING | 5000.00 |
    | ACCOUNTING | MILLER | 1300.00 |
    ±-----------±-------±--------+
    3 rows in set (0.00 sec)

在这里插入图片描述

  • 显示各个员工的姓名,工资,及工资级别

    mysql> select ename,sal,grade from emp,salgrade where sal between losal and hisal;
    mysql> select ename,sal,grade from emp,salgrade where sal between losal and hisal;
    ±-------±--------±------+
    | ename | sal | grade |
    ±-------±--------±------+
    | SMITH | 800.00 | 1 |
    | ALLEN | 1600.00 | 3 |
    | WARD | 1250.00 | 2 |
    | JONES | 2975.00 | 4 |
    | MARTIN | 1250.00 | 2 |
    | BLAKE | 2850.00 | 4 |
    | CLACK | 2450.00 | 4 |
    | SCOTT | 3000.00 | 4 |
    | KING | 5000.00 | 5 |
    | TURNER | 1500.00 | 3 |
    | ADAMS | 1100.00 | 1 |
    | JAMES | 950.00 | 1 |
    | FORD | 3000.00 | 4 |
    | MILLER | 1300.00 | 2 |
    ±-------±--------±------+
    14 rows in set (0.00 sec)

在这里插入图片描述

3.自连接

自连接是指在同一张表连接查询

案例:

显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号–empno)

使用的子查询

select ename,empno from emp where empno=(select mgr from emp where ename='FORD');

使用多表查询(自查询)

select e2.ename,e2.empno from emp e1,emp e2 where e1.ename='FORD' and e1.mgr=e2.empno;
mysql> select e1.ename,e2.empno from emp e1,emp e2 where e1.ename='FORD' and e1.mgr=e2.empno;
+-------+--------+
| ename | empno  |
+-------+--------+
| FORD  | 007566 |
+-------+--------+
1 row in set (0.00 sec)

在这里插入图片描述

4.子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询

4.1单行子查询

返回一行记录的子查询

  • 显示SMITH同一部门的员工

    select * from emp where deptno=(select deptno from emp where ename=‘SMITH’);
    mysql> select * from emp where deptno=(select deptno from emp where ename=‘SMITH’);
    ±-------±------±--------±-----±--------------------±--------±-----±-------+
    | empno | ename | job | mgr | hiredate | sal | comm | deptno |
    ±-------±------±--------±-----±--------------------±--------±-----±-------+
    | 007369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800.00 | NULL | 20 |
    | 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL | 20 |
    | 007788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL | 20 |
    | 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |
    | 007902 | FORD | ANALYST | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL | 20 |
    ±-------±------±--------±-----±--------------------±--------±-----±-------+
    5 rows in set (0.00 sec)

在这里插入图片描述

4.2多行子查询

返回多行记录的子查询

  • in关键字;查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的

    select ename,job,sal,deptno from emp where job in(select job from emp where deptno=10) and deptno<>10;
    mysql> select ename,job,sal,deptno from emp where job in(select job from emp where deptno=10) and deptno<>10;
    +-------+---------+---------+--------+
    | ename | job     | sal     | deptno |
    +-------+---------+---------+--------+
    | JONES | MANAGER | 2975.00 |     20 |
    | BLAKE | MANAGER | 2850.00 |     30 |
    | SMITH | CLERK   |  800.00 |     20 |
    | ADAMS | CLERK   | 1100.00 |     20 |
    | JAMES | CLERK   |  950.00 |     30 |
    +-------+---------+---------+--------+
    5 rows in set (0.00 sec)
    
  • all关键字;显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号

    // 使用聚合函数
    select ename,sal,deptno from emp where sal>(select max(sal) from emp where deptno=30);
    mysql> select ename,sal,deptno from emp where sal>(select max(sal) from emp where deptno=30);
    +-------+---------+--------+
    | ename | sal     | deptno |
    +-------+---------+--------+
    | JONES | 2975.00 |     20 |
    | SCOTT | 3000.00 |     20 |
    | KING  | 5000.00 |     10 |
    | FORD  | 3000.00 |     20 |
    +-------+---------+--------+
    4 rows in set (0.01 sec)// 使用all关键子
    select ename,sal,deptno from emp where sal>all(select sal from emp where deptno=30);
    mysql> select ename,sal,deptno from emp where sal>all(select sal from emp where deptno=30);
    +-------+---------+--------+
    | ename | sal     | deptno |
    +-------+---------+--------+
    | JONES | 2975.00 |     20 |
    | SCOTT | 3000.00 |     20 |
    | KING  | 5000.00 |     10 |
    | FORD  | 3000.00 |     20 |
    +-------+---------+--------+
    4 rows in set (0.00 sec)
    
  • any关键字;显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工)

    // 使用聚合函数
    mysql> select ename,sal,deptno from emp where sal > (select min(sal) from emp where deptno=30) and deptno<>30;
    ±-------±--------±-------+
    | ename | sal | deptno |
    ±-------±--------±-------+
    | JONES | 2975.00 | 20 |
    | CLACK | 2450.00 | 10 |
    | SCOTT | 3000.00 | 20 |
    | KING | 5000.00 | 10 |
    | ADAMS | 1100.00 | 20 |
    | FORD | 3000.00 | 20 |
    | MILLER | 1300.00 | 10 |
    ±-------±--------±-------+
    7 rows in set (0.00 sec)
    // 使用any关键字
    mysql> select ename,sal,deptno from emp where sal > any(select sal from emp where deptno=30) and deptno<>30;
    ±-------±--------±-------+
    | ename | sal | deptno |
    ±-------±--------±-------+
    | JONES | 2975.00 | 20 |
    | CLACK | 2450.00 | 10 |
    | SCOTT | 3000.00 | 20 |
    | KING | 5000.00 | 10 |
    | ADAMS | 1100.00 | 20 |
    | FORD | 3000.00 | 20 |
    | MILLER | 1300.00 | 10 |
    ±-------±--------±-------+
    7 rows in set (0.00 sec)

4.3多列子查询

单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言

的,而多列子查询则是指查询返回多个列数据的子查询语句

案例:查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人

mysql> select * from emp where (deptno,job)=(select deptno,job from emp where ename='SMITH') and ename<>'SMITH';
mysql> select * from emp where (deptno,job)in(select deptno,job from emp where ename='SMITH') and ename<>'SMITH';
+--------+-------+-------+------+---------------------+---------+------+--------+
| empno  | ename | job   | mgr  | hiredate            | sal     | comm | deptno |
+--------+-------+-------+------+---------------------+---------+------+--------+
| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL |     20 |
+--------+-------+-------+------+---------------------+---------+------+--------+
1 row in set (0.00 sec)

4.4在from子句中使用子查询

子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。

案例:

显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资

答案:

select t1.ename,t1.deptno,t1.sal,t2.myavg from emp t1,(select deptno,avg(sal) myavg from emp group by deptno) t2 where t1.deptno=t2.deptno and t1.ssal > t2.myavg;

步骤:

// 1.根据部门号分组得到每组的平均工资
mysql> select avg(sal) from emp group by deptno;
+-------------+
| avg(sal)    |
+-------------+
| 2916.666667 |
| 2175.000000 |
| 1566.666667 |
+-------------+
3 rows in set (0.00 sec)// 2.根据部门号分组得到每组的平均工资和部门号
mysql> select deptno,avg(sal) from emp group by deptno;
+--------+-------------+
| deptno | avg(sal)    |
+--------+-------------+
|     10 | 2916.666667 |
|     20 | 2175.000000 |
|     30 | 1566.666667 |
+--------+-------------+
3 rows in set (0.00 sec)// 3.将上面得到的结果与emp表做笛卡尔积
mysql> select * from emp t1,(select deptno,avg(sal) myavg from emp group by deptno) t2 where t1.deptno=t2.deptno;
+--------+--------+-----------+------+---------------------+---------+---------+--------+--------+-------------+
| empno  | ename  | job       | mgr  | hiredate            | sal     | comm    | deptno | deptno | myavg       |
+--------+--------+-----------+------+---------------------+---------+---------+--------+--------+-------------+
| 007369 | SMITH  | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 |     20 | 2175.000000 |
| 007499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 |     30 | 1566.666667 |
| 007521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 |     30 | 1566.666667 |
| 007566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 |     20 | 2175.000000 |
| 007654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 |     30 | 1566.666667 |
| 007698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 |     30 | 1566.666667 |
| 007782 | CLACK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 |     10 | 2916.666667 |
| 007788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 |     20 | 2175.000000 |
| 007839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 |     10 | 2916.666667 |
| 007844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 |     30 | 1566.666667 |
| 007876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 |     20 | 2175.000000 |
| 007900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 |     30 | 1566.666667 |
| 007902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 |     20 | 2175.000000 |
| 007934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 |     10 | 2916.666667 |
+--------+--------+-----------+------+---------------------+---------+---------+--------+--------+-------------+
14 rows in set (0.00 sec)// 5.增加筛选条件 :工资大于平均工资
mysql> select * from emp t1,(select deptno,avg(sal) myavg from emp group by deptno) t2 where t1.deptno=t2.deptno and t1.sal > t2.myavg;
+--------+-------+-----------+------+---------------------+---------+--------+--------+--------+-------------+
| empno  | ename | job       | mgr  | hiredate            | sal     | comm   | deptno | deptno | myavg       |
+--------+-------+-----------+------+---------------------+---------+--------+--------+--------+-------------+
| 007499 | ALLEN | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 | 300.00 |     30 |     30 | 1566.666667 |
| 007566 | JONES | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |   NULL |     20 |     20 | 2175.000000 |
| 007698 | BLAKE | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |   NULL |     30 |     30 | 1566.666667 |
| 007788 | SCOTT | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |   NULL |     20 |     20 | 2175.000000 |
| 007839 | KING  | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |   NULL |     10 |     10 | 2916.666667 |
| 007902 | FORD  | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |   NULL |     20 |     20 | 2175.000000 |
+--------+-------+-----------+------+---------------------+---------+--------+--------+--------+-------------+
6 rows in set (0.00 sec)// 5.根据题目要求得到结果
mysql> select t1.ename,t1.deptno,t1.sal,t2.myavg from emp t1,(select deptno,avg(sal) myavg from emp group by deptno) t2 where t1.deptno=t2.deptno and t1.ssal > t2.myavg;
+-------+--------+---------+-------------+
| ename | deptno | sal     | myavg       |
+-------+--------+---------+-------------+
| ALLEN |     30 | 1600.00 | 1566.666667 |
| JONES |     20 | 2975.00 | 2175.000000 |
| BLAKE |     30 | 2850.00 | 1566.666667 |
| SCOTT |     20 | 3000.00 | 2175.000000 |
| KING  |     10 | 5000.00 | 2916.666667 |
| FORD  |     20 | 3000.00 | 2175.000000 |
+-------+--------+---------+-------------+
6 rows in set (0.00 sec)

查找每个部门工资最高的人的姓名、工资、部门、最高工资

答案:

select t1.ename,t1.sal,t1.deptno,t2.mymax from emp t1,(select deptno, max(sal) mymax from emp group by deptno) t2 where t1.deptno=t2.deptno and t1..sal=t2.mymax;

步骤:

// 1.得到分组之后的部门号和最高工资
mysql> select deptno, max(sal) from emp group by deptno;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
|     20 |  3000.00 |
|     30 |  2850.00 |
+--------+----------+
3 rows in set (0.01 sec)// 2.与emp表进行笛卡尔积并进行t1.sal=t2.mymax的筛选(工资等于最高工资)
mysql> select * from emp t1,(select deptno, max(sal) mymax from emp group by deptno) t2 where t1.deptno=t2.deptno and t1.sal=t2.mymax;
+--------+-------+-----------+------+---------------------+---------+------+--------+--------+---------+
| empno  | ename | job       | mgr  | hiredate            | sal     | comm | deptno | deptno | mymax   |
+--------+-------+-----------+------+---------------------+---------+------+--------+--------+---------+
| 007698 | BLAKE | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL |     30 |     30 | 2850.00 |
| 007788 | SCOTT | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL |     20 |     20 | 3000.00 |
| 007839 | KING  | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 | NULL |     10 |     10 | 5000.00 |
| 007902 | FORD  | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL |     20 |     20 | 3000.00 |
+--------+-------+-----------+------+---------------------+---------+------+--------+--------+---------+
4 rows in set (0.00 sec)// 3.根据题目要求选择需要筛选的内容
mysql> select t1.ename,t1.sal,t1.deptno,t2.mymax from emp t1,(select deptno, max(sal) mymax from emp group by deptno) t2 where t1.deptno=t2.deptno and t1..sal=t2.mymax;
+-------+---------+--------+---------+
| ename | sal     | deptno | mymax   |
+-------+---------+--------+---------+
| BLAKE | 2850.00 |     30 | 2850.00 |
| SCOTT | 3000.00 |     20 | 3000.00 |
| KING  | 5000.00 |     10 | 5000.00 |
| FORD  | 3000.00 |     20 | 3000.00 |
+-------+---------+--------+---------+
4 rows in set (0.00 sec

显示每个部门的信息(部门名,编号,地址)和人员数量

答案:

select t1.deptno,t1.dname,t1.loc,t2.num from dept t1,(select deptno,count(*) num from emp group by deptno) t2 where t1.deptno=t2.deptno;

步骤:

// 1.分组得到每一组的人数
mysql> select deptno,count(*) num from emp group by deptno;
+--------+-----+
| deptno | num |
+--------+-----+
|     10 |   3 |
|     20 |   5 |
|     30 |   6 |
+--------+-----+
3 rows in set (0.00 sec)// 2.和部门表进行笛卡尔积,然后进行条件筛选
mysql> select * from dept t1,(select deptno,count(*) num from emp group by deptno) t2 where t1.deptno=t2.deptno;
+--------+------------+----------+--------+-----+
| deptno | dname      | loc      | deptno | num |
+--------+------------+----------+--------+-----+
|     10 | ACCOUNTING | NEW YORK |     10 |   3 |
|     20 | RESEARCH   | DALLAS   |     20 |   5 |
|     30 | SALES      | CHICAGO  |     30 |   6 |
+--------+------------+----------+--------+-----+
3 rows in set (0.01 sec)
mysql> select t1.deptno,t1.dname,t1.loc,t2.num from dept t1,(select deptno,count(*) num from emp group by deptno) t2 where t1.deptno=t2.deptno;
+--------+------------+----------+-----+
| deptno | dname      | loc      | num |
+--------+------------+----------+-----+
|     10 | ACCOUNTING | NEW YORK |   3 |
|     20 | RESEARCH   | DALLAS   |   5 |
|     30 | SALES      | CHICAGO  |   6 |
+--------+------------+----------+-----+
3 rows in set (0.00 sec)

暴力解法:

mysql> select dept.dname,dept.deptno,dept.loc,count(*) from emp,dept where emp.deptno=dept.deptno group by dept.deptno,dept.dname,dept.loc;
+------------+--------+----------+----------+
| dname      | deptno | loc      | count(*) |
+------------+--------+----------+----------+
| ACCOUNTING |     10 | NEW YORK |        3 |
| RESEARCH   |     20 | DALLAS   |        5 |
| SALES      |     30 | CHICAGO  |        6 |
+------------+--------+----------+----------+
3 rows in set (0.01 sec)

总结:

解决多表问题的本质:想办法将多表转化为单表,所以mysql中,所有select的问题全部都可以转化成单表问题

4.5合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all

4.5.1 union

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。

案例:将工资大于2500或职位是MANAGER的人找出

// 1.查出工资大于2500的
mysql> select * from emp where sal>2500;
+--------+-------+-----------+------+---------------------+---------+------+--------+
| empno  | ename | job       | mgr  | hiredate            | sal     | comm | deptno |
+--------+-------+-----------+------+---------------------+---------+------+--------+
| 007566 | JONES | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
| 007698 | BLAKE | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL |     30 |
| 007788 | SCOTT | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL |     20 |
| 007839 | KING  | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 | NULL |     10 |
| 007902 | FORD  | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL |     20 |
+--------+-------+-----------+------+---------------------+---------+------+--------+
5 rows in set (0.00 sec)// 2.查出job=MANAGER的
mysql> select * from emp where job='MANAGER';
+--------+-------+---------+------+---------------------+---------+------+--------+
| empno  | ename | job     | mgr  | hiredate            | sal     | comm | deptno |
+--------+-------+---------+------+---------------------+---------+------+--------+
| 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
| 007698 | BLAKE | MANAGER | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL |     30 |
| 007782 | CLACK | MANAGER | 7839 | 1981-06-09 00:00:00 | 2450.00 | NULL |     10 |
+--------+-------+---------+------+---------------------+---------+------+--------+
3 rows in set (0.00 sec)// 3.进行合并
mysql> select * from emp where sal>2500 union select * from emp where job='MANAGER';
+-------+-------+-----------+------+---------------------+---------+------+--------+
| empno | ename | job       | mgr  | hiredate            | sal     | comm | deptno |
+-------+-------+-----------+------+---------------------+---------+------+--------+
|  7566 | JONES | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
|  7698 | BLAKE | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL |     30 |
|  7788 | SCOTT | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL |     20 |
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 | NULL |     10 |
|  7902 | FORD  | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL |     20 |
|  7782 | CLACK | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 | NULL |     10 |
+-------+-------+-----------+------+---------------------+---------+------+--------+
6 rows in set (0.00 sec)
4.5.2 union all

操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

案例:将工资大于25000或职位是MANAGER的人找出来

// 1.查出工资大于2500的
mysql> select * from emp where sal>2500;
+--------+-------+-----------+------+---------------------+---------+------+--------+
| empno  | ename | job       | mgr  | hiredate            | sal     | comm | deptno |
+--------+-------+-----------+------+---------------------+---------+------+--------+
| 007566 | JONES | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
| 007698 | BLAKE | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL |     30 |
| 007788 | SCOTT | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL |     20 |
| 007839 | KING  | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 | NULL |     10 |
| 007902 | FORD  | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL |     20 |
+--------+-------+-----------+------+---------------------+---------+------+--------+
5 rows in set (0.00 sec)// 2.查出job=MANAGER的
mysql> select * from emp where job='MANAGER';
+--------+-------+---------+------+---------------------+---------+------+--------+
| empno  | ename | job     | mgr  | hiredate            | sal     | comm | deptno |
+--------+-------+---------+------+---------------------+---------+------+--------+
| 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
| 007698 | BLAKE | MANAGER | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL |     30 |
| 007782 | CLACK | MANAGER | 7839 | 1981-06-09 00:00:00 | 2450.00 | NULL |     10 |
+--------+-------+---------+------+---------------------+---------+------+--------+
3 rows in set (0.01 sec)// 3.进行合并
mysql> select * from emp where sal>2500 union all select * from emp where job='MANAGER';
+-------+-------+-----------+------+---------------------+---------+------+--------+
| empno | ename | job       | mgr  | hiredate            | sal     | comm | deptno |
+-------+-------+-----------+------+---------------------+---------+------+--------+
|  7566 | JONES | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
|  7698 | BLAKE | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL |     30 |
|  7788 | SCOTT | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL |     20 |
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 | NULL |     10 |
|  7902 | FORD  | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL |     20 |
|  7566 | JONES | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
|  7698 | BLAKE | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL |     30 |
|  7782 | CLACK | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 | NULL |     10 |
+-------+-------+-----------+------+---------------------+---------+------+--------+
8 rows in set (0.00 sec)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/707625.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android LiveData Cannot add the same observer with different lifecycles

https://www.yxhuang.com/2022/05/29/livedata-add-some-observer-error/ 这篇文章已经解释的很好了。 其实在去年我写的文章&#xff0c; https://blog.csdn.net/jzlhll123/article/details/126593235 中提到了&#xff0c; 其实不论是java或者kotlin&#xff0c;不引用外部的…

C语言字符串处理函数

C语言提供了丰富的字符串处理函数&#xff0c;可以对字符串进行输入、输出、合并、修改、比较、转换、复制、搜索等操作&#xff0c;使用这些现成的函数可以大大减轻我们的编程负担。 用于输入输出的字符串函数&#xff0c;例如printf、puts、scanf、gets等&#xff0c;使用时要…

计算机找不到ffmpeg.dll怎么办,这5种方法可快速解决

ffmpeg.dll 是一个在计算机系统中扮演重要角色的动态链接库&#xff08;DLL&#xff09;文件&#xff0c;它的功能与多媒体处理领域紧密相关。该文件作为 FFmpeg&#xff08;快速前进移动图像专家组&#xff09;项目的核心组件之一&#xff0c;承载着实现多种音频、视频编解码及…

Nginx网络服务六-----IP透传、调度算法和负载均衡

1.实现反向代理客户端 IP 透传 就是在日志里面加上一个变量 Module ngx_http_proxy_module [rootcentos8 ~]# cat /apps/nginx/conf/conf.d/pc.conf server { listen 80; server_name www.kgc.org; location / { index index.html index.php; root /data/nginx/html/p…

代码随想录算法训练营第三十六天|435 无重叠区间、763 划分字母区间、56合并区间

435 无重叠区间 题目链接&#xff1a;无重叠区间 思路 这道题目和昨天最后一道射弓箭的题目很相似。我们找到重叠的区域有几个&#xff0c;那也就是要移除几个区域后剩下的区域不重叠。所以这道题目可以变为找重叠区域的问题。 class Solution { public:static bool cmp(co…

BLEU: a Method for Automatic Evaluation of Machine Translation

文章目录 BLEU: a Method for Automatic Evaluation of Machine Translation背景和意义技术原理考虑 n n n - gram中 n 1 n1 n1 的情况考虑 n n n - gram中 n > 1 n\gt 1 n>1 的情况考虑在文本中的评估初步实验评估和结论统一不同 n n n 值下的评估数值考虑句子长度…

从C到C++

二、从C到C 本章介绍一些C拓展的非面向对象功能。 引用&#xff08;掌握&#xff09; 1.1 概念 引用从一定程度上讲是一个指针的平替&#xff0c;几乎被所有面向对象编程语言所使用。引用相当于对某一个目标变量起”别名“。 操作引用与操作原变量完全一样。 #include <iost…

Vue3 Hooks函数使用及封装思想

一、什么是Hooks函数&#xff1f; 想象一下&#xff0c;你在做饭&#xff0c;有一些调料你经常会用到&#xff0c;比如盐、酱油和辣椒。每次做饭时&#xff0c;你都会从柜子里拿出这些调料。如果你每次用完都把它们随便放在厨房的某个角落&#xff0c;下次做饭时就可能找不到它…

如何获取Header??

两种获取Header的方式&#xff1a; 原始方式&#xff1a; RestController RequestMapping("/param") public class ParamController {//如何获取HeaderRequestMapping("/getHeader")public String getHeader(HttpServletRequest request){String userAge…

springboot之jdbc、druid、mybatis

springboot整合jdbc spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.52.3:3306/mybatis?useUnicodetrue&characterEncodingutf-8&serverTimezoneUTCusername: rootpassword: root<?xml version"1.0" encodi…

trie树(前缀树)

前缀树 1. 前缀树的的介绍2.前缀树的实现2.1插入功能2.2删除功能2.3查找前缀和查找单词功能2.4 哈希表版本 1. 前缀树的的介绍 在计算机科学中&#xff0c;trie&#xff0c;又称前缀树或字典树&#xff0c;是一种有序树&#xff0c;用于保存关联数组&#xff0c;其中的键通常是…

MarkDown实用技巧:MarkDown中如何实现换行?

MarkDown实用技巧&#xff1a;MarkDown中如何实现换行&#xff1f; &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 &#x1f448; 希望…

计讯物联5G RedCap网关TG463化繁为简,推动5G赋能千行百业

5G RedCap&#xff0c;全称为Reduced Capability&#xff0c;即在5G的基础上&#xff0c;对部分功能进行化繁为简后形成的新技术标准&#xff0c;故又称轻量化5G。作为高性价比下的精简技术&#xff0c;5G RedCap技术具备成本低、低功耗、兼顾5G等特点&#xff0c;能够在确保应…

【Android安全】Windows 环境下载 AOSP 源码

准备环境 安装 git 安装 Python 硬盘剩余容量最好大于 800G 打开 Git Bash&#xff0c;用 git 克隆源代码仓库 git clone https://android.googlesource.com/platform/manifest.git //没有梯子使用清华源 git clone https://aosp.tuna.tsinghua.edu.cn/platform/manifest.git这…

代码随想录算法训练营第36天 | 738.单调递增的数字 ,968.监控二叉树

贪心算法章节理论基础&#xff1a; https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 738.单调递增的数字 题目链接&#xff1a;https://leetcode.cn/problems/monotone-increasing-digits/ 思路&#xff1a; …

论文精读--VAE

自编码器(Auto-Encoder)是学一个特征能够代表输入的图像 而VAE则为数据的隐变量加上先验——将隐变量限制为一个标准正态分布&#xff0c;也就是学一个具有代表性的分布 Abstract How can we perform efficient inference and learning in directed probabilistic models, in…

鸿蒙linux内核的L1设备服务开发详解

鸿蒙linux内核的L1设备服务开发详解 ​ 鸿蒙基于linux内核的L1设备的系统基于面向服务架构&#xff0c;提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务进程、进程间服务调用的开发能力。现对此基座下的服务进行剖析并以实例方式进行讲解。 一、简介 在L1设备…

git忽略某些文件(夹)更改方法

概述 在项目中,常有需要忽略的文件、文件夹提交到代码仓库中,在此做个笔录。 一、在项目根目录内新建文本文件,并重命名为.gitignore,该文件语法如下 # 以#开始的行,被视为注释. # 忽略掉所有文件名是 a.txt的文件. a.txt # 忽略所有生成的 java文件, *.java # a.j…

Time Travel

题目链接 解题思路 由于所有边集中的边加起来的总和至多为&#xff0c;无向图即&#xff0c;可以存下所以直接对所有边集中的边进行建边&#xff0c;同时对于每条边&#xff0c;记录其所在边集号对于每个边集&#xff0c;由大到小维护其能通过的时间点然后从1号跑最短路到当前…

Flutter开发框架

Flutter 技术栈是指用于构建应用程序的一系列技术和工具&#xff0c;这些技术和工具都是围绕 Flutter 框架组织的。Flutter 是由谷歌开发的开源 UI 开发工具包&#xff0c;用于从单一代码库开发跨平台应用程序&#xff0c;包括 Android、iOS、Web、以及桌面应用程序&#xff08…