mysql子查询自我总结

mysql子查询

mysql子查询,为什么会有子查询这个东西喃?
来个例子,像是Python中的嵌套循环是一样的,当我们相对我们之前的一个查询结果在进行查询的时候,子查询就出现了基本的样子就是在我们select中又包含了一个select。
子查询与之相对的有个父查询,最外层的select语句就是我们的父查询语句,里面的使我们的子查询语句当然在语句中所有的子查询语句都是在小括号中的,你也可以判断为在小括号中的语句就是子查询语句。
在查询过程中,子查询先于父查询执行(因为我们是要对以及查询出来的结果进行再次查询,那么我们最先的就是要得到我们第一次查询的结果)。
子查询语句按照其出现的位置可以分为:
①select后面 ②from后面 ③where/having后面 ④exits后面
按照结果集的行列不同可以分为:
①标量子查询(结果集只有一行一列)
②列子查询也称为多子查询(结果集一列多行)
③行子查询(结果集有一行多列)
④表子查询(结果集一般为多行多列)
标题后面的①②③是说他可以使用上面按结果集来分类的第①②③种情况。
在子查询中,子查询语句一般是在小括号中,子查询语句一般放在条件的右侧,标量子查询一般搭配当行操作符使用 (in any /some/all)
哎呀看来又得说一下什么是单行操作符了。来吧。
in/ont in
等于列表中的任意一个值都可以返回。例如:
a in(10,12,14)在a中的值等于其中任意一个时都可以返回。not in相反
any/some
和子查询中返回的某一个值比较,例如:
a>any(10,12,14)当a大于其中任意一个值时就返回,就相当于当a大于列表中最小值时就返回出来
all
与列表中的所有值相比较,例如:
a>all(10,12,14)就是当a大于列表中所有的值时返回
相当于a大于列表中的最大值时就会返回结果出来
当然在涉及到单行操作符时后面只是支持标量子查询,否则属于非法查询(无意义的查询)。
查询一个部门里面最低工资大于50号部门最低工资的部门id和他的最低工资。

select min(salary),department_id
  from employees
  group by department_id
  having min(salary) (
            select min(salary)
            from employees
            where department_id=50 );

列子查询
列子查询和行子查询这两种子查询一般都是位于where或者having后面。
列子查询来个例子吧:
查询location_id是1400或者1700的部门中所有员工的姓名
我们来分步来讲解一下,要查询上述结果,我们首先要得到location_id是1400或者1700的部门名。

SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700);

这样得到我们的结果:
在这里插入图片描述
可以看到我们的结果集属于一列多行的内容,是符合我们列子查询的特征。
在我们得到部门号之后就可以查询到我们部门的员工姓名

SELECT last_name 
FROM employees
WHERE department_id IN(SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700));

得到结果:

在这里插入图片描述
在上面的代码里面我们使用到了两次in ,因为我们的结果都是多个结果所以使用in来进行匹配。当然,在我们不知道的情况下也可以直接使用in,因为无论后面的结果是一个或者是多个使用in都可以匹配。
这个就是列子查询的使用啦。
行子查询
接下来我们来看看行子查询,行子查询的结果集为一行多列,或者多行多列。
当我们在使用筛选条件时使用同一个操作符进行比较时,就可以用行子查询来代替。
例如我们需要查询工资最高,工号最小的员工是哪一位,按照我们正常的书写就应该是

Select last_name
From employees
Where employee_id=
(select min(employee_id )from employees)
and salary =(select max(salary) from employees);

这样书写就会显得比较麻烦,那么利用到行子查询就会简单很多
试试:

select *
From employees
Where (employee_id,salary) = 
(
Select min(employee_id),max(salary)
From employees);

这两种查询方式是一样的,只是使用行子查询数据更加方便一点,书写的简洁一点。
结果:
在这里插入图片描述
行子查询就是说将我们前面的数据逐条的与后面的数据进行匹配,然后输出。
你可以将我们的employees表认为是一张表,将表中的employee_id和salary与我们子查询中查询出来的最小编号和最大工资相匹配然后输出。
表子查询
表子查询一般用于from后面,这个就相当于将我们的查询结果视为一张表,并且一定要为我们的查询结果的表起别名,便于区分。
例如:查询每个部门的平均工资的工资等级
第一步我们先查询每个部门们的平均工资

Select avg(salary) ag ,department_id from employees;

在这里插入图片描述
然后我们将我们的结果视为一张表,将他与表job_grades连接查询

Select ag_dep.*,g.grade_level
From (
Select avg(salary) ag ,department_id from employees
Group by department_id
) ag_dep
Inner join job_grade g
On ag_dep.ag between lowest_sal and highest_sal;

在这里插入图片描述
结果就出来啦。在表子查询中一定要记得,将我们的子查询结果视为一张表取个别名,然后进行其他的操作。
exists后面的子查询
Exists后面的子查询(相关子查询)
Exists后面子查询是判断子查询结果是否存在,属于一种布尔类型
例如:查询在employees中是否存在department_id

Select exists (select department_id from employees);

在这里插入图片描述
可以看到返回值只是一个1,这也就是说当我们后面的查询结果存在时会返回1,反之则返回0。
这样各位是不是想到了我们之前的多行操作符 “in”,当然,只要能使用exists的情况in同样可以使用。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值