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

news2024/11/19 7:43:00
文章目录
  • 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.coloradmin.cn/o/1478786.html

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

相关文章

vue项目中使用antv X6新手教程,附demo案例讲解(可拖拽流程图、网络拓扑图)

前言&#xff1a; 之前分别做了vue2和vue3项目里的网络拓扑图功能&#xff0c;发现对antv X6的讲解博客比较少&#xff0c;最近终于得闲码一篇了&#xff01; 需求&#xff1a; 用户可以自己拖拽节点&#xff0c;节点之间可以随意连线&#xff0c;保存拓扑图数据后传给后端&…

Java学习笔记------权限修饰符和抽象类、抽象方法

权限修饰符的分类 代码块 局部代码块 public class test{public static void main(String[] args){int a10;System.out.println(a);} } { int a10; System.out.println(a); }即是局部代码块 构造代码块 构造代码块优先于构造方法执行 静态代码块 格式…

不要神话了AI / GPT(人工智能 和 GPT)-尽量用一张图说明(将持续更新)

很多人一听到 AI&#xff0c; GPT &#xff0c;Chat-GPT&#xff0c; 智能驾驶&#xff0c;智能这个&#xff0c;智能那个&#xff0c; ..... 就觉得 噢&#xff0c; 好 牛皮 呀&#xff0c; 其实这个东西算个啥&#xff1f; 争取 用一张图 把 他的 根 给 刨出来&#xff08;刨…

如何提取测试点

如何提取测试点 首先会想到从需求文档中提取测试点&#xff0c;每一次迭代之后&#xff0c;都会有需求&#xff0c;需求经理评审之后&#xff0c;我们要基于需求去写测试计划&#xff0c;包括梳理出来的测试点&#xff0c;梳理完测试点之后&#xff0c;编写对应的测试用例&…

面试笔记系列三之spring基础知识点整理及常见面试题

目录 如何实现一个IOC容器? 说说你对Spring 的理解&#xff1f; 你觉得Spring的核心是什么&#xff1f; 说一下使用spring的优势&#xff1f; Spring是如何简化开发的&#xff1f; IOC 运行时序 prepareRefresh() 初始化上下文环境 obtainFreshBeanFactory() 创建并…

阿里Java开发手册(黄山版) LeetCode刷题手册 免费下载

目录 一、阿里Java开发手册(黄山版) 二、LeetCode刷题手册 三、获取方式 今天给大家推荐两个程序员的辅助利器&#xff01;都是平时开发&#xff0c;刷算法能经常用到的书籍&#xff0c;怕百度云分享会失效&#xff0c;获取方式在最下面&#xff0c;永久有效。 一、阿里Jav…

网络编程作业day2

1.将TPC和UDP通信模型各敲两遍 &#xff08;1&#xff09;TPC通信模型&#xff1a; 服务器代码&#xff1a; #include <myhead.h> #define SERVER_IP "192.168.125.136" #define SERVER_PORT 1314 int main(int argc, const char *argv[]) {//1、创建用于监…

Python进阶学习:Pandas--查看DataFrame中每一列的数据类型

Python进阶学习&#xff1a;Pandas–查看DataFrame中每一列的数据类型 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希…

如何扫描试卷把它变成电子档?分享3个宝藏软件!

在数字化时代&#xff0c;纸质试卷的电子化已成为许多学生和工作人员的需求。将试卷扫描成电子档不仅方便存储和传输&#xff0c;还能提高学习效率。那么&#xff0c;如何将试卷快速、准确地转换成电子档呢&#xff1f;本文将为您介绍几种实用的扫描软件及其使用方法。 一、拍试…

基于51单片机的心率血压体温检测系统[proteus仿真]

基于51单片机的心率血压体温检测系统[proteus仿真] 健康检测系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个基于51单片机的心率血压体温检测系统 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 2&#xff…

数据结构与算法 - 数组与二分查找 + Leetcode典型题

1. 什么是数组 数组是存放在连续内存空间上的相同类型数据的集合。 数组可以方便的通过下标索引的方式获取到下标下对应的数据。 C中二维数组在地址空间上也是连续的。 需注意&#xff1a; 数组的下标从0开始。数组内存空间的地址是连续的。数组的元素是不能删的&#xff0c…

深度学习 精选笔记(7)前向传播、反向传播和计算图

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

如何制作一款建材商城微信小程序

现在&#xff0c;微信小程序已经成为了很多企业和商家开展线上业务的重要渠道之一。对于建材商城而言&#xff0c;制作一款专属的微信小程序可以帮助企业更好地展示产品、提供服务&#xff0c;并增加销售额。下面将介绍如何制作一款建材商城微信小程序。 首先&#xff0c;登录【…

CSS-显示模式,背景,盒子模型

1. 元素显示模式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style…

接口测试实战--mock测试、日志模块

一、mock测试 在前后端分离项目中,当后端工程师还没有完成接口开发的时候,前端开发工程师利用Mock技术,自己用mock技术先调用一个虚拟的接口,模拟接口返回的数据,来完成前端页面的开发。 接口测试和前端开发有一个共同点,就是都需要用到后端工程师提供的接口。所以,当…

【LeetCode:124. 二叉树中的最大路径和 + 二叉树+递归】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【GAD】动态图的半监督异常检测

SAD: Semi-Supervised Anomaly Detection on Dynamic Graphs Limitations of existing semi-supervised methodsContributionRelated workMethodDeviation Networks with Memory BankContrastive Learning for Unlabeled Samples Experiments少样本评估2D t-SNE可视化消融实验 …

Machine Vision Technology:Lecture1 Introduction

Machine Vision Technology&#xff1a;Lecture1 Introduction What kind of information can we extract from an image?Syllabus organized fromRoadmap路线图 计算机视觉&#xff08;本科&#xff09; 北京邮电大学 鲁鹏 What kind of information can we extract from an …

一张图读懂人工智能

一、生成人工智能的概念和应用&#xff0c;以及如何使用大型语言模型进行聊天和创造原创内容。这项技术将会对人类和企业产生深远影响。 计算机获得学习、思考和交流的能力&#xff0c;被称为生成人工智能。生成人工智能可以立即获得人类所有知识的总和&#xff0c;并回答任何…

OSCP靶场--Shenzi

OSCP靶场–Shenzi 考点(1.目录扫描&#xff1a;可以尝试使用多个工具(扫描不出来任何东西&#xff0c;可以结合机器名拼接url 2.WP 目标插入webshell getshell 3.windows环境AlwaysInstallElevated提权) 1.nmap扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC -p- …