【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,一经查实,立即删除!

相关文章

计算机找不到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…

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…

如何获取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…

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

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

Time Travel

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

高级语言期末2011级A卷(软件学院)

1.编写函数&#xff0c;判定正整数m和n&#xff08;均至少为2&#xff09;是否满足&#xff1a;数m为数n可分解的最小质因数&#xff08;数n可分解的最小质因数为整除n的最小质数&#xff09; 提示&#xff1a;判定m为质数且m是n的最小因数 #include <stdio.h> #include…

DiffiT | 英伟达提出用于图像生成的扩散ViT架构DiffiT,达成新SOTA!

本文首发于AIWalker&#xff0c;欢迎关注。 https://arxiv.org/abs/2312.02139 https://github.com/NVlabs/DiffiT 扩散模型以其强大的表达能力和高样本质量在许多领域得到了新的应用。对于样本生成&#xff0c;这些模型依赖于通过迭代去噪生成图像的去噪神经网络。然而&#…

坚持刷题|二叉树展开为链表

文章目录 题目考察点代码实现实现总结扩展问题用递归的方式实现在展开二叉树为链表的过程中&#xff0c;递归和迭代两种方法各有什么优缺点&#xff1f;可能的扩展问题 Hello&#xff0c;大家好&#xff0c;我是阿月。坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;今天刷&…

LTD营销枢纽2023年度功能升级回顾

在过去的2023年&#xff0c;我们的团队致力于不断进步和创新。经过一年的不懈努力&#xff0c;我们共发布了50次的系统升级&#xff0c;引入了16种全新的解决方案与业务应用&#xff0c;并实施了1363项各类细致优化。 这些更新和改进不仅在我们的营销枢纽系统现有功能的基础上实…

35岁程序员,深入理解JVM的核心知识点

网络&#xff1a;分层模型、TCP、UDP、HTTP、HTTPS 分层模型 应用层&#xff1a;负责处理特定的应用程序细节&#xff0c;如 HTTP、FTP、DNS运输层&#xff1a;为两台主机提供端到端的基础通信&#xff0c;如 TCP、UDP网络层&#xff1a;控制分组传输、路由选择等&#xff0c…

【大数据架构(1)】Lambda Architecture – Realtime Data Processing 论文重点翻译

文章目录 1. INTRODUCTION2. LAMBDA ARCHITECTUREA) BATCH LAYERB) SPEED LAYERC) SERVICE LAYER 3. LIMITATIONS OF THE TRADITIONAL LAMBDAARCHITECTURE4. A PROPOSED SOLUTION1. 架构说明2. 前后架构改进对比 1. INTRODUCTION Lambda架构背后的需求是由于虽然MR能够处理大数…