MySQL(复合查询)

这篇具有很好参考价值的文章主要介绍了MySQL(复合查询)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0 前言

相关内容已经准备好了

  • 链接:https://gitee.com/ding-xushengyun/linux__cpp/blob/master/scott_data.sql
    准备工作,创建一个雇员信息表(来自oracle 9i的经典测试表)
    • emp员工表
    • dept部门表
    • salgrade工资等级表

1 基本查询

  • 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的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` 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 | CLARK  | 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 |
+--------+--------+-----------+------+---------------------+---------+---------+--------+
14 rows in set (0.00 sec)

  • 使用年薪进行降序排序
mysql> select `ename`, `sal`*12+ifnull(`comm`, 0) '年薪' from `emp` order by 年薪 desc;
+--------+----------+
| ename  | 年薪     |
+--------+----------+
| KING   | 60000.00 |
| SCOTT  | 36000.00 |
| FORD   | 36000.00 |
| JONES  | 35700.00 |
| BLAKE  | 34200.00 |
| CLARK  | 29400.00 |
| ALLEN  | 19500.00 |
| TURNER | 18000.00 |
| MARTIN | 16400.00 |
| MILLER | 15600.00 |
| WARD   | 15500.00 |
| ADAMS  | 13200.00 |
| JAMES  | 11400.00 |
| SMITH  |  9600.00 |
+--------+----------+
14 rows in set (0.00 sec)

  • 显示工资最高的员工的名字和工作岗位
mysql> select `ename`, `job` from `emp` where `sal` = (select max(`sal`) from `emp`);
+-------+-----------+
| ename | job       |
+-------+-----------+
| KING  | PRESIDENT |
+-------+-----------+
1 row in set (0.00 sec)


  • 显示工资高于平均工资的员工信息
mysql> select `ename`, `sal` from `emp` where `sal` > (select avg(`sal`) from `emp`);
+-------+---------+
| ename | sal     |
+-------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING  | 5000.00 |
| FORD  | 3000.00 |
+-------+---------+
6 rows in set (0.00 sec)
  • 显示每个部门的平均工资和最高工资
mysql> select `deptno`, avg(`sal`), max(`sal`) from `emp` group by `deptno`;
+--------+-------------+------------+
| deptno | avg(`sal`)  | max(`sal`) |
+--------+-------------+------------+
|     10 | 2916.666667 |    5000.00 |
|     20 | 2175.000000 |    3000.00 |
|     30 | 1566.666667 |    2850.00 |
+--------+-------------+------------+
3 rows in set (0.00 sec)

  • 显示平均工资低于2000的部门号和它的平均工资
mysql> select `deptno`, avg(`sal`) '平均工资' from `emp` group by `deptno` having 平均工资<2000;
+--------+--------------+
| deptno | 平均工资     |
+--------+--------------+
|     30 |  1566.666667 |
+--------+--------------+
1 row in set (0.00 sec)

  • 显示每种岗位的雇员总数,平均工资
mysql> select `job`, count(*), format(avg(`sal`), 2) from `emp` group by `job`;
+-----------+----------+-----------------------+
| job       | count(*) | format(avg(`sal`), 2) |
+-----------+----------+-----------------------+
| ANALYST   |        2 | 3,000.00              |
| CLERK     |        4 | 1,037.50              |
| MANAGER   |        3 | 2,758.33              |
| PRESIDENT |        1 | 5,000.00              |
| SALESMAN  |        4 | 1,400.00              |
+-----------+----------+-----------------------+
5 rows in set (0.00 sec)

2 多表查询

  • 多表查询本质就是穷举
    MySQL(复合查询)
    (—此图来自于相关资料)

  • 实际有效数据为下面所示:

mysql> select * from emp, dept where emp.deptno=dept.deptno;
+--------+--------+-----------+------+---------------------+---------+---------+--------+--------+------------+----------+
| empno  | ename  | job       | mgr  | hiredate            | sal     | comm    | deptno | deptno | dname      | loc      |
+--------+--------+-----------+------+---------------------+---------+---------+--------+--------+------------+----------+
| 007369 | SMITH  | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 |     20 | RESEARCH   | DALLAS   |
| 007499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 |     30 | SALES      | CHICAGO  |
| 007521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 |     30 | SALES      | CHICAGO  |
| 007566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 |     20 | RESEARCH   | DALLAS   |
| 007654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 |     30 | SALES      | CHICAGO  |
| 007698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 |     30 | SALES      | CHICAGO  |
| 007782 | CLARK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 |     10 | ACCOUNTING | NEW YORK |
| 007788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 |     20 | RESEARCH   | DALLAS   |
| 007839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 |     10 | ACCOUNTING | NEW YORK |
| 007844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 |     30 | SALES      | CHICAGO  |
| 007876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 |     20 | RESEARCH   | DALLAS   |
| 007900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 |     30 | SALES      | CHICAGO  |
| 007902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 |     20 | RESEARCH   | DALLAS   |
| 007934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 |     10 | ACCOUNTING | NEW YORK |
+--------+--------+-----------+------+---------------------+---------+---------+--------+--------+------------+----------+
14 rows in set (0.00 sec)

  • 示部门号为10的部门名,员工名和工资
mysql> select `dname`, `ename`, `sal` from `emp`, `dept` where emp.deptno=dept.deptno and emp.deptno=10;
+------------+--------+---------+
| dname      | ename  | sal     |
+------------+--------+---------+
| ACCOUNTING | CLARK  | 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`;
+--------+---------+-------+
| 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 |
| CLARK  | 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)

  • 使用的子查询:
mysql> select empno, ename from emp where empno = (select mgr from emp where ename='FORD');
+--------+-------+
| empno  | ename |
+--------+-------+
| 007566 | JONES |
+--------+-------+
1 row in set (0.02 sec)

  • 使用多表查询(自查询)
mysql> select e1.empno, e1.ename from emp e1, emp e2 where e1.empno=e2.mgr and e2.ename='FORD';
+--------+-------+
| empno  | ename |
+--------+-------+
| 007566 | JONES |
+--------+-------+
1 row in set (0.00 sec)

4 子查询

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

4.1 单行子查询

返回一行记录的子查询

  • 显示SMITH同一部门的员工
mysql> select ename from emp where deptno=(select deptno from emp where ename='SMITH');
+-------+
| ename |
+-------+
| SMITH |
| JONES |
| SCOTT |
| ADAMS |
| FORD  |
+-------+
5 rows in set (0.00 sec)

4.2 多行子查询

返回多行记录的子查询

  • in关键字;查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的
mysql> select ename, job, sal, deptno from emp where job in (select distinct job from emp where deptnoo=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的所有员工的工资高的员工的姓名、工资和部门号
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 > any(select sal from emp where deptno=30);
+--------+---------+--------+
| ename  | sal     | deptno |
+--------+---------+--------+
| ALLEN  | 1600.00 |     30 |
| WARD   | 1250.00 |     30 |
| JONES  | 2975.00 |     20 |
| MARTIN | 1250.00 |     30 |
| BLAKE  | 2850.00 |     30 |
| CLARK  | 2450.00 |     10 |
| SCOTT  | 3000.00 |     20 |
| KING   | 5000.00 |     10 |
| TURNER | 1500.00 |     30 |
| ADAMS  | 1100.00 |     20 |
| FORD   | 3000.00 |     20 |
| MILLER | 1300.00 |     10 |
+--------+---------+--------+
12 rows in set (0.00 sec)

4.3 多列子查询

  • 查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人
mysql> select ename from emp where (deptno, job) = (select deptno, job from emp where ename='SMITH') and ename!!='SMITH';
+-------+
| ename |
+-------+
| ADAMS |
+-------+
1 row in set (0.00 sec)

4.4 在from子句中使用子查询

子查询语句出现在from子句中。

  • 显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资
mysql> select ename, emp.deptno, sal, format(myavg, 2)  from emp, (select avg(sal) myavg, deptno from emp groupp by deptno) tmp where emp.deptno=tmp.deptno and emp.sal>tmp.myavg;
+-------+--------+---------+------------------+
| ename | deptno | sal     | format(myavg, 2) |
+-------+--------+---------+------------------+
| KING  |     10 | 5000.00 | 2,916.67         |
| JONES |     20 | 2975.00 | 2,175.00         |
| SCOTT |     20 | 3000.00 | 2,175.00         |
| FORD  |     20 | 3000.00 | 2,175.00         |
| ALLEN |     30 | 1600.00 | 1,566.67         |
| BLAKE |     30 | 2850.00 | 1,566.67         |
+-------+--------+---------+------------------+
6 rows in set (0.00 sec)

  • 查找每个部门工资最高的人的姓名、工资、部门、最高工资
mysql> select ename, sal, deptno, maxsal from emp, (select max(sal) maxsal from emp group by deptno) tmp where sal=maxsal;
+-------+---------+--------+---------+
| ename | sal     | deptno | maxsal  |
+-------+---------+--------+---------+
| 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)

  • 显示每个部门的信息(部门名,编号,地址)和人员数量
mysql> select dept.deptno, dept.dname, dept.loc, count from dept, (select deptno, count(*) count from emp groupp by deptno) tmp where tmp.deptno=dept.deptno;
+--------+------------+----------+-------+
| deptno | dname      | loc      | count |
+--------+------------+----------+-------+
|     10 | ACCOUNTING | NEW YORK |     3 |
|     20 | RESEARCH   | DALLAS   |     5 |
|     30 | SALES      | CHICAGO  |     6 |
+--------+------------+----------+-------+
3 rows in set (0.01 sec)

4.5 合并查询

合并多个select的执行结果,可以使用集合操作符 union,union all

4.5.1 union

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

  • 将工资大于2500或职位是MANAGER的人找出来
mysql> select ename, sal, job from emp where sal > 2500 union
    -> select ename, sal, job from emp where job='MANAGER';
+-------+---------+-----------+
| ename | sal     | job       |
+-------+---------+-----------+
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| SCOTT | 3000.00 | ANALYST   |
| KING  | 5000.00 | PRESIDENT |
| FORD  | 3000.00 | ANALYST   |
| CLARK | 2450.00 | MANAGER   |
+-------+---------+-----------+
6 rows in set (0.00 sec)

4.5.3 union all

该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行文章来源地址https://www.toymoban.com/news/detail-429409.html

mysql> select ename, sal, job from emp where sal > 2500 union all select ename, sal, job from emp where job='MAANAGER';
+-------+---------+-----------+
| ename | sal     | job       |
+-------+---------+-----------+
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| SCOTT | 3000.00 | ANALYST   |
| KING  | 5000.00 | PRESIDENT |
| FORD  | 3000.00 | ANALYST   |
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| CLARK | 2450.00 | MANAGER   |
+-------+---------+-----------+
8 rows in set (0.01 sec)

到了这里,关于MySQL(复合查询)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【MySQL】复合查询

    可以在SQL语句内部进行子查询, 先执行内部SQL,再执行外部SQL 。 实际上很多时候我们要查的数据可能不在同一张表,所以需要多表查询。 比方说一张表里面有2行信息,另一个表里面有3行信息,如果直接 select * form 表1,表2 那么就会在表中进行 穷举组合(得到的结果称为笛

    2024年02月12日
    浏览(35)
  • 【MySQL】 复合查询

    下面给出三张表,分别是员工表(emp)、部门表(dept)和工资等级表(salgrade)。 后续所要进行的查询操作都将以这三张表作为数据源,包括基本查询和复合查询。 通过下面的练习能够评估你的SQL查询的基本功。 雇员信息表数据库文件 三张表单 员工表(emp) 雇员编号(

    2024年02月19日
    浏览(41)
  • MySQL——复合查询

    目录 一.基本查询回顾 二. 多表查询 三.自连接 四.子查询 1.单行子查询 2.多行子查询  3.多列子查询 4.在from子句中使用子查询 5.合并查询 准备数据库: 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J:  按照部门号升序而雇员的工资降序排序

    2024年02月04日
    浏览(50)
  • MySQL - 第8节 - MySQL复合查询

    目录 1.基本查询回顾 2.多表查询 3.自连接 4.子查询 4.1.单行子查询 4.2.多行子查询 4.2.1.in 4.2.2.all 4.2.3.any 4.3.多列子查询 4.4.在from子句中使用子查询 5.合并查询 准备测试表: • 下面给出三张表,分别是员工表(emp)、部门表(dept)和工资等级表(salgrade)

    2024年02月10日
    浏览(43)
  • 【MySQL学习】MySQL表的复合查询

    对MySQL表的基本查询还远远达不到实际开发过程中的需求,因此还需要掌握对数据库表的复合查询。本文介绍了多表查询、子查询、自连接、内外连接等复合查询的案例。 来自oracle 9i的经典测试表: emp员工表 dept部门表 salgrade工资等级表 MySQL表的基本查询都是针对一张表进行

    2024年02月03日
    浏览(37)
  • elasticsearch[二]-DSL查询语法:全文检索、精准查询(term/range)、地理坐标查询(矩阵、范围)、复合查询(相关性算法)、布尔查询

    elasticsearch 的查询依然是基于 JSON 风格的 DSL 来实现的。 Elasticsearch 提供了基于 JSON 的 DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有 :查询出所有数据,一般测试用。例如:match_all 全文检索(full text)查询 :利用分词器对用户输入内容分词,然后去

    2024年01月18日
    浏览(60)
  • 【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询

    「前言」文章内容大致是对MySQL复合查询的学习。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 前面篇章讲解的mysql表的查询都是对一张表进行查询,在实际开发中这远远不够,下面将讲解复合查询,首先回顾一下基本的查询。 使用的数据库是之前篇章的雇

    2024年02月11日
    浏览(50)
  • MySQL:内置函数、复合查询和内外连接

    select  函数;   实际开发中往往数据来自不同的表,所以需要多表查询。本节我们用一个简单的公司管理系统,有三张 表EMP,DEPT,SALGRADE来演示如何进行多表查询。 如果说 表1有n条记录,表2有m条记录,那么笛卡儿积之后就有n * m条记录。 在实际应用中,为了合并多个select的执

    2024年02月13日
    浏览(62)
  • MySQL子查询相关使用

    SQL文件链接在最下面 MySQL子查询相关使用 子查询的实质: 一个 select 语句的查询结果能够作为另一个语句的输入值。子查询不仅可用于 where 子句中,还能够用于 from 子句中,此时子查询的结果将作为一个临时表(temporary table)来使用。   一、      单行子查询   1、 查询

    2024年02月09日
    浏览(36)
  • MySQL查询优化方案汇总(索引相关)

    类型隐式转换 大坑 大数据深度分页,用主键 避免使用MySQL函数 避免类型的隐式转换 避免使用函数或表达式,尽量只让数据库做纯粹的增删改查。 避免使用不等值做排除法 避免使用null值 减少大字段查询,避免使用*,不说磁盘io的损耗,连网络带宽都跟着损耗。 如果只sel

    2024年03月09日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包