MySQL基础--多表查询--各种子查询

这些都是我自学时手打到文本文档,在复制粘贴到博客的,有一些命令格式不对,但全部百分百原创,如果有疑问或者不对的地方,欢迎评论区指正,也可以加q群592383030来探讨(我就是自学的普通人,不卖课,不涉及补习机构)

我会出一整套mysql的学习过程,从基础的sql语句,约束,函数,事务。到进阶的存储引擎,sql优化,索引,存储过程,锁,触发器,视图甚至lnnoDB引擎的详解和一些运维方面的比如,mha主从,读写分离;mmm双主,pxc MySQL高可用,zabbix,elk监控MySQL。如果有需要来我主页,有帮助到您就关注我点个赞。

 八,子查询概念

概念:sql语句中嵌套select语句,称为嵌套查询,又称子查询。
select  *  from  表名  where  columnl=(select  columnl  form  表2);
外部可以是查询语句也可以是增删改查(insert,update,delete,select)
根据结果不同分为四类
1,标量子查询:子查询返回的是一个值只有一行一列
2,列子查询:   子查询返回结果有一列
3,行子查询:   子查询返回结果有一行
4,表字查询:   子查询返回多行多列

也根据查询位置,分为:where之后,from之后,select之后

                                                  九,标量子查询

标量子查询:返回的是一个值只有一行一列。(数据表里有很多行和列,不管回报的值有多少字,只要它在表里只占一格,就代表是一个值,就是标量子查询,
比如查一个日期会返回一串数字,但一个日期只占一格,就是标量子查询;你查两个年龄,可能才四个数字但占了两格,但那就不是一个值,用列子查询)
常用的符号基本就是比较运算符:<>  >  >=  <  <=(根据需求写关系)
例子1,查询销售部所有员工信息。
分析:员工表里没有部门信息,只有部门id,部门外键连接到部门表的主键id。
第一步:查到销售部id
select  id  from  部门表名  where  name=‘销售部’
就是查询部门表的id字段,过滤条件是只查出叫销售部的id。即可得出销售部id
第二步:根据部门id查出员工信息
select  *  from  员工表名  where  部门id=4;
就是查询员工表所有字段(也就是员工所有信息),加上过滤条件是只查出部门id为4(上一步查出销售部id为4)的员工信息。即可查出所有销售部员工信息

但是这种方法要两步,麻烦。今天学的子查询就是把两句sql连在一起,可以用子查询一条命令搞点。
select  *  from  员工表名  where  部门id=(select  id  from  部门表名  where  name=‘销售部’)
因为后面括号里的子查询的结果只有一个值,所以也称标量子查询。
等于命令基本一样,就是揉到一句了,本身id等于4,不写4了,直接连上算出4的过程。

例子2,查询 张君杰(任意员工名,方便理解我都写张君杰了) 入职之后入职的员工
第一步:查询张君杰的入职日期
select  入职日期  from  员工表  where  name=‘张君杰’;
就是查询员工表里的入职日期字段,加上过滤条件 名字等于张君杰。即可查出张君杰的入职时间
第二步:查询指定入职时间(就是张君杰入职时间)之后入职的员工
select  *  from  员工表  where  入职时间  > '2022 -04 -12';
就是查询员工表所有字段,加个过滤条件,只查出入职时间大于2020-04-12(上一步得出的张君杰入职时间)的员工

还是用标量子查询揉成一句话
select  *  from  员工表  where  入职时间  >(select  入职日期  from  员工表  where  name=‘张君杰’);
就是要查入职时间大于2022 -04 -12,现在不写2022 -04 -12了,而是把算出这个日期的过程直接连在后面。

                                                  十,列子查询

 返回结果有一列(可以是多行),这种子查询称之为列子查询
查多少字段有多少列,查多少人有多少行。以第一个例子的子查询来说,查的只是不同部门的部门id,字段只有一个,所以只有一列,但是查不同部门的所以会有多行。
第二个例子的子查询来说,查工资一个字段,只有一列,不同的员工组成不同行。所以例子1,2都是列子查询,子查询结果只有一列(多行但是正常)
常用的操作符:in、notin、any、some、all
这些符号后面三个是新认识的,详细讲一讲
in             在指定的集合范围之内,符合任意一个就行
notin        不在指定的集合范围内
any           子查询返回结果,满足任意一个就行
some        与any等同,使用some的地方都可以用any
all             子查询返回的所有值必须都满足

例子1,查询销售部和市场部的员工信息
第一步:查询销售部和市场部的部门id
select  id  from  部门表名  where  name =‘销售部’or  name =‘市场部’;
就是查询部门表id字段,加上筛选条件 名字字段名 等于 销售部  和  名字字段 等于 市场部;就能查出销售部id=2和市场部id=4
第二步:根据部门id查员工
select  *  from  员工表名  where 部门id  in(2,4);
就是查询员工表所有字段,加个过滤条件,部门id要等于2或4(上一步查出的两个部门id,并且调用in函数,两个条件满足一个即可)。就只查出销售部和市场部员工了

继续通过子查询揉成一句话(因为括号里子查询的结果是一列;同样的字段,只是有多个结果,就用列子查询)
select  *  from  员工表名  where 部门id  in(select  id  from  部门表名  where  name =‘销售部’or  name =‘市场部’);
一样的,本身写in(2,4)现在不写2,4了。写2和4出来的过程。

例子2,查询所有  比财务部所有人工资都高  的员工
第一步:查询财务部所有人工资
先要算出财务部部门id
select  id  from  员工表名  where  name=’财务部‘;
就是查询部门表的id字段,加上筛选条件名字=财务部。就得出了财务部的部门id。

在根据部门id,在员工表里查出财务部所有人工资
select  工资字段名  from  员工表  where  部门id=3(假设上一步求出来的财务部id=3);
就是查询员工表的工资字段,加上筛选条件,id=3,就只得出财务部所有的员工工资。

再把第一步的两句话用例子查询揉成一句话
select  工资字段名  from  员工表  where  部门id=(select  id  from  员工表名  where  name=’财务部‘);
就是本身部门id等于3,现在不写3,把上一步算出三的过程写进去,就变成一句话了。假设这里查出了,20000,25000,27000.

第二步:在根据上一步查出的财务部所有人工资,查出比他们都高的员工。
select  *  from  员工表  where  工资字段名  > 27000

用子查询把一二步连一起
select  *  from  员工表  where  工资字段名  > all(select  工资字段名  from  员工表  where  部门id=(select  id  from  员工表名  where  name=’财务部‘)):
直接把上一步得出财务部工资的过程写进括号里,调用了比较符>还有运算符all函数,就是括号里子查询出的所有结果必须全都大于。

                                                  十一,行子查询

查多少字段有多少列,查多少员工有多少行。以例子1的子查询来说,只查张君杰一个人,的不同字段(工资和领导id),就代表只有一行,但是有多列。所以例子1是行子查询
行子查询常用操作符:=、<>、in、not  in
例子1,查询张君杰(任意员工,为了方便理解,都以张君杰为例)的薪资相同,领导相同的员工。
第一步:查询张君杰的薪资和直属领导。
select  薪资字段名  领导id字段名  from  员工表  where  name=’张君杰‘;(假设查询结果是薪资=15000;领导id=3)
就是查员工表的薪资字段和领导id字段,筛选名字字段=张君杰。就查出了张君杰的薪资和领导id
第二步:根据上一步结果,查询和张君杰相同的员工。
select  *  from  员工表名  where  salary  =15000 and  领导id = 3;
这就查询员工表所有字段(等于查员工详细信息),加个筛选条件调用了and,既满足前面薪资字段=15000又满足后面领导id字段=3
注意!!!这种调用and的语法无法使用子查询来揉成一句话
可以不用and,换种写法:
select  *  from  员工表名  where(薪资字段名,领导id字段名)=(15000,3)
这句和上面那句查询结果一模一样,就是语法不同,把where条件的字段名和定义,分别都用括号括起来,用逗号隔开,默认一 一对应。都是完成第二步的sql语句!!!但是这种语法可以用子查询把一二步揉成一句话

用行子查询揉成一句话
select  *  from  员工表名  where(薪资字段名,领导id字段名)=(select  薪资字段名  领导id字段名  from  员工表  where  name=’张君杰‘);
其实这句前面和第二步第二种语法一模一样,区别就在where条件,前面的字段名也是一样的,就后面的定义括号不同,本身应该写15000和3,但是现在写算出这两个数的过程,也就是第一步。

                                                  十二,表子查询

子查询结果是一张表,多行多列
查多少字段有多少列,查多少员工有多少行。以例子1的子查询来说,张君杰与大牛逼,两个人代表多行;薪资字段和职位字段,两个字段代表多列。所以符合表子查询
常用字符,in。多出现在from之后,
例子1,查询与 张君杰 与 大牛逼 职位和薪资相同 的员工
第一步:查询张君杰和大牛逼的薪资和职位
select  职位字段名,薪资字段名  form  员工表  where  名字字段=’张君杰‘or name = ‘大牛逼’;
就是查员工表的职位字段和薪资字段,加上where条件筛选,名字字段=张君杰或者大牛逼。就得出了张君杰和大牛逼的职位和薪资
第二步,查询与第一步结果匹配的其它员工(直接用了表子连接)
select  *  from  员工表名  where(职位字段名,薪资字段名)in(select  职位字段名,薪资字段名  form  员工表  where  名字字段=’张君杰‘or name = ‘大牛逼’);
!!!注意我第二步直接就用表子连接,连起来了。
就是查询员工表的职位字段和薪资字段,加个where条件过滤,按照上一章讲的,应该是分别两个括号,前面写字段名,后面写定义,中间=号连接就好了
但是这里不行,不能写=。因为是多行多列,要用in。in就是前面 职位字段名,薪资字段名的组,必须满足一组,比如和张君杰职位,薪资一样;要么和大牛逼职位薪资一样。

例子2,查询入职日期在2022-4-12日之后的员工信息和所属部门信息
第一步:查询入职在该日期之后的员工
select  *  from  员工表名  where  入职时间 > ‘2022-04-12‘;
就是查询员工表的所有字段(更详细的员工信息)加个where条件,入职时间字段要大于2022-04-12.就能得出在该时间之后入职的员工信息
第二步:查出该部分员工的部门信息
这一步有点复杂,因为员工表并没有记录部门,只有部门id对应另一张部门表。所以需要做外键连接,用上一步的结果,做成临时表,用临时表去连接部门表(这样才能得出符合条件员工的部门信息),并且我们本表还没分部门的员工也要查出来所以做左外连接。
select  e.*,d.*  from(select  *  from  员工表名  where  入职时间 > ‘2022-04-12‘) e  left  join  部门表 d  on e.部门id = d.id;
按执行顺序来翻译,查询由括号里的第一步得出的临时表,并把此表起别名为 e。在调用left  join左外连接到部门表,并把此表起别名为d。再on后加连接条件(用来过滤无用项)就让e表的部门id=d表的id。在查询e表和d表的所有字段。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值