九、MySQL数据库之HAVING与子查询

之前我们说这个GROUP BY 的时候,说了一下这个HAVING啊,我差点给忘记了,今天一起和子查询一起都给它说了,省的到时候忘记了再

HAVING

先来说这个HAVING,HAVING和这个WHERE类似,可以说是一对兄弟,但是呢,又不一样。

我们来这么举栗子,好比现在要统计中国每个地区的人口,然后呢,把人口超过1000万的城市给它列举出来,顺便输出一下具体的内个人口数量。我们大概写一下这个SQL语句。

SELECT 城市名字,COUNT(1) from 中国 WHERE count(1) > 1000万 GROUP BY 城市名字 

大概就这样吧,将就看一下,接下来我们分析。

我们这个SQL,应该是先把这个中国的所有城市进行划分,然后去统计每个城市的人口,统计好之后,我们再去进行查询人口数量超过1000万的,但是,我们看上面的这个SQL,虽然说写了,但是我和大家说,这个语句是查不出来的。为什么呢?

原因很简单,这里需要说一下这个SQL的执行情况,(我先说,各位先听,我后面会有章节进行细讲的)SQL语句拿到之后,是先执行from的,然后拿到数据,通过WHERE进行筛选的,但是啊,各位,我们根本没有办法拿到这个count(1),因为这个值我们只能在GROUP BY 之后,统计完成后,才能拿到,所以说啊,这个SQL是一个错误的SQL,并且会报错。

那我们如何去实现上面的业务呢?

这时候,HAVING骑着动感单车就来了。

HAVING呢,它是可以再GROUP BY 之后实现筛选各种数据,也就是说,它可以做到我们上面所说的问题。怎么用这个HAVING呢?

SELECT 城市名字,COUNT(1) from 中国 GROUP BY 城市名字 HAVING count(1) > 1000万

这货是写在我们GROUP BY 的,从而我们也可以发现啊,WHERE 是写在GROUP BY 之前的,而HAVING是写在之后的。而这个也是他们的执行顺序。

当然啦,如果你说同时去使用WHERE 和 HAVING可以不,我的答案是,可以的。我们这里呢,用一下我们的内个学生表。

先查询一下所有的学生。

然后我们查询名字是张三的学生

再然后,我们跟HAVING,我们再加一个岁数是13岁的。我们先跟在WHERE后面去写。

我们发现,是可以的,现在再改成12岁

也是OK的。这次,我们将WHERE 和 HAVING换一下顺序。

直接报错,说明啊,这个having只能跟在where后面 from xxx表 where .... .... having...

只能这样啊,别写错了!!!

 

子查询

上面讲完了这个having之后,接着我们来说一下这个子查询。

这个子查询指的是什么呢?我直接上百度百科好了,我虽然知道,就怕说的不准确~~~

通过画线的句子,我们可以知道,其实就是将一个查询出来的结果,当做另外一个查询的条件。

知道什么是子查询之后,我们来说一下这个子查询到底怎么用。

带IN关键词的子查询

我们前面好像没有说这个IN关键词,正好在这里将一下,IN就是指的是在什么什么里,那怎么用呢?

select column from xxx表 where column IN (xxx,xxx,xxx....);

大概就这样,什么什么字段,在什么什么里面,当然了,说多了都是废话,我们直接上手。

我们就查询一下我们的学生表中,年龄是12 或者是13的学生。如果按照以前,我们是这么去写的。

但是这么写有缺点,如果你这个条件多了,自己到时候写的懵逼了,那就完蛋了。

所以我们引入IN,我们再来看。

是不是,也是可以的。当然了,除去直接写这样固定的值以外,我们还可以写动态的。

比如说,我们现在要查询一下班级名称叫 高一一班 和 高一四班 的所有学生。我们可以这样去写。

第一步,我们先查询一下这两个班级。

第二步,我们将这个查询当做一个子集,然后嵌套在另外一个子集中。而且,我们学生表和班级表可以通过这个classId 进行关联,所以,直接上SQL

但是,你以为这样就可以使用了吗?我们呢,先运行一下,看看有啥问题没有。

报错了,我们来看一下是什么错误。

它说操作数应该包含一列。

我们这样去想,我们最初的IN,里面写的是一个一个的数,12 13 等,但是这个子集中,是返回的三列数据,除去id以外,还有className,还有一个teacher,所以啊,sql就懵了,in里面只需要一列集合即可,但是子集中提供了三列。

所以,我们修改一下子集中的SQL,我们只要让他查到一个id即可,其他的我们不要。

是不是,这样SQL就知道了,因为我们只返回了一列给主查询。当然,有IN,就有NOT IN,我们再来运行。

同样,是没有问题的。

带比较运算的子查询

这个呢,和上面的in类似,我们再来举一个例子,好比现在要查找一下,年龄超过12岁的。

看,按照以前写,我们是这么去写的,我们现在修改一下,我们将12这个进行动态化。

是不是,我们将一个子查询作为了一个值,然后给主查询当条件。(这里主要一下子找不到合适的需求,就用这个意思意思)

但是,我们将12 改成 12,13,我们再来看一下。

看啊,有是内个错误,所以说大家要注意一下这个问题。

带EXISTS的子查询

直接举一个例子,如果存在班级,我们就去查询所有的学生。

这里呢,我们就会使用到这个exists。用法:

select xxx from xxx表 where exists ...

大概就是这样,我们来使用一下

如果select * from t_class 查询出东西了,那么就去查询所有的学生,当然,也可以在exists前面加一个not

 

大家好好消化一下,一定要多去练习。有问题可以联系我QQ:2100363119

 

  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

他 他 = new 他()

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值