MySQL数据库(8)—— 复合查询

目录

一,基本查询回顾

二,多表查询

2.1 关于多表查询

2.2 笛卡尔积

2.3 部分演示

三,自连接

四,子查询

4.1 单行子查询

4.2 多行子查询

4.3 多列子查询

4.4 from子句使用子查询

五,合并查询


一,基本查询回顾

我们还是以我们MySQL数据库(6)中创建的scott表做演示:MySQL数据库(6)—— 表的增删查改_mysql表删改字段-优快云博客

下面是三张表的各字段:

员工表(emp):

  • 雇员编号(empno)
  • 雇员姓名(ename)
  • 雇员职位(job)
  • 雇员领导编号(mgr)
  • 雇佣时间(hiredate)
  • 工资月薪(sal)
  • 奖金(comm)
  • 部门编号(deptno)

 部门表dept:

  • 部门编号(deptno)
  • 部门名称(dname)
  • 部门所在地点(loc)

工资等级表(salgrade) :

  • 等级(grade)
  • 此等级最低工资(losal)
  • 此等级最高工资(hisal)

 ①查询工资高于500或岗位为MANAGER的员工,并且要求是姓名首字母为J的员工

②查询员工信息,按部门号升序并且按员工工资降序 

③查询员工信息,按年薪降序排序

④查询工资最高的员工的名字和岗位 

完成这步操作我们需要两次查询,第一次是先查询最高工资具体数目,然后根据这个数目再查询对应员工和岗位,但是我们也可以使用子查询,如下:

⑤查询工资高于平均工资的员工信息 

⑥查询每个部门的平均工资和最高工资 

⑦查询平均工资低于2000的部门号和它的平均工资 

⑧查询每种岗位的雇员总数和平均工资 

二,多表查询

2.1 关于多表查询

  • 我们上面的一些查询操作都是针对emp表这一张表来的,而在实际开发中其实需要将多张表关联起来查询,这叫做“多表查询”
  • 我们只需要把要查询的多个表放到from后面再以逗号隔开即可,这时MySQL会给这多张表取笛卡尔积,作为多表查询的数据源
  • 多表查询的本质就是个多张表取笛卡尔积,然后再在笛卡尔积中进行查询,简单来说就是把多张表合成一个大表,然后在大表中进行查询

2.2 笛卡尔积

所谓的对多张表取笛卡尔积,就是以类似穷举的方式,得到这多张表的记录中的所有可能组成的集合,比如下面就是没做任何处理的将员工表和部门表做笛卡尔积的结果:

  • 前半部分是员工表的列信息,后半部分是部门表的列信息
  • 取笛卡尔积时,会先从员工表中取第一条记录然后和部门表的四个记录依次做拼接,然后再从员工表取第二条记录再次做拼接,这样当取完员工表的最后一条记录后,就完成了笛卡尔积的大表 

笛卡尔积的过滤 

在上面的表格中我们可以看到,我们多张表做笛卡尔积后,有很多数据是重复的,也就是无意义的

实际上一个员工只有和自己所在的部门信息进行组合才是有意义的,也就是两张表对应的部门号列相同时,这条数据才是有意义的,如下:

通过 表名.表列 的形式就可以单独获取一张表里的单列啦

2.3 部分演示

①显示部门号为10的部门名、员工名和员工工资

②显示各个员工姓名、工资和工资级别

三,自连接

上面我们是对不同表进行笛卡尔积,当然我们也可以对一张表做笛卡尔积,如果一张表中的某个字段能够将表中的多条记录关联起来,那么就可以通过自连接将表中通过该字段关联的记录组合起来

①显示员工姓名为“FORD”的上级领导的编号和姓名 

我们可以用子查询先查询到FORD的领导的编号,再根据领导的编号去查询领导的名字:

可以看到上面的主查询和子查询都用到的是emp表,所以我们可以将emp表煜emp表做一次笛卡尔积,如下:

四,子查询

前面我们已经简单使用过子查询了,也叫做嵌套查询,分为单行子查询、多行子查询、多列子查询以及在from字句中使用的子查询

4.1 单行子查询

①显示与SMITH员工在同一部门的员工

此外,也可以用自连接搞定这道题:

4.2 多行子查询

多行子查询是指返回多行单列数据的子查询

①显示与10号部门下岗位相同的别的部门的员工的信息,不包含10号部门的员工(in关键字)

②显示工资比“30号部门的所有员工的工资”高的员工的名字、工资和部门号(all关键字)

我们也可以用单行子查询找到30号部门的最高工资,然后找到工资大于该最高工资的的员工信息:

③查询工资比“30号部门任意员工的工资”高的员工的姓名、工资和部门号,包含30号部门员工 

这道题也可以等价于找到比“30号部门最低工资”高的员工信息:

4.3 多列子查询

多列子查询是指返回多列数据的子查询

①显示和SMITH的部门和岗位完全相同的员工,不包括SMITH本人

  • 多列子查询得到的结果是多列数据,在比较多列数据时需要将待比较的多个列用括号括起来,如上图
  • 多列子查询返回的如果是多行数据,那么也是也可以用in、all和any关键字进行筛选的,只是多列查询的表比较复杂,需要仔细甄别

4.4 from子句使用子查询

子查询语句不仅可以出现在where字句中,也可以出现在from字句中,其查询结果将会被当作一个临时表使用

①显示每个高于“自己部门平均工资”的员工的平均工资

②显示每个部门工资最高的员工名字、工资、部门和部门最高工资 

③显示每个部门的部门名、部门编号、所在地和员工数量 

这道题也可以用多表查询来解决: 

五,合并查询

是将多个查询结果进行合并,使用的操作符有两个:

  • union:用于取得两个查询结果的并集,会去掉重复行
  • union all:也用取得两个查询结果的并集,但是不去掉重复行

①查询工资大于2500或者职位是MANAGER的员工

查询工资大于2500和职位是MANAGER的两个SQL如下:

然后我们可以使用一句SQL将这两个SQL连起来,称为合并查询:

注意:待合并的两个查询结果的列数必须一样,否则无法合并 

### 复杂查询技术概述 在MySQL中执行复杂查询通常涉及多种技术和优化方法。这些技术不仅能够提高查询效率,还能帮助处理更复杂的业务逻辑。 #### 使用索引进行排序 通过利用索引来检索按顺序排列的行而无需单独的排序操作是一种常见的优化方式。例如,在`SELECT ... FROM tbl_name ORDER BY key_part1, key_part2,...`语句中,如果指定的关键字部分已经建立了合适的索引,则可以显著减少查询时间[^1]。同样地,对于降序排序的情况(如`ORDER BY key_part1 DESC, key_part2 DESC...`),也可以应用类似的原理来提升性能。 #### 范围查询优化 范围查询是指基于某个字段值区间内的记录查找过程。为了使这类查询更加高效,可以通过创建覆盖索引或者复合索引来实现更好的访问路径规划。尽管这种方法确实能增强系统的整体表现力,但由于其实施起来较为繁琐且成本较高,因此并不是唯一的解决方案选项[^2]。 #### 数据库基础概念回顾 理解什么是表格以及它们是如何构成的是构建任何有效SQL查询的基础之一。“表”代表了一种针对特定种类数据所建立起来的一种结构化的列表形式;其中,“特定类型”的含义指向某一类别的资料集合——像客户详情、交易历史等等,并且每张表都应该围绕单一主题展开描述而不应混入其他无关类别下的属性项。“结构化清单”,则意味着实际存储单元会被进一步细分成若干子要素以便于管理和分析工作开展得更为顺畅合理些。比如说当涉及到顾客档案管理时就可以把整个信息体系划分为姓名栏位、联系方式栏目以及其他个人偏好设定等方面来进行分类归纳整理成条理清晰易于读取的形式呈现出来给使用者查看参考之用[^4]。 #### 随机选取记录的方法 有时候我们可能需要从结果集中随机抽取一条或多条记录展示给前端界面显示。这时可以先确定好想要获取的数量上限再从中挑选一个小于此数值作为偏移量参数填入LIMIT子句当中完成最终目标达成效果[^5]。 ```sql -- Example of using INDEX for efficient ordering. SELECT * FROM employees WHERE department_id = 10 ORDER BY hire_date ASC; -- Range Query with Composite Index Usage. EXPLAIN EXTENDED SELECT * FROM products WHERE price BETWEEN 10 AND 50; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值