MySQL(二):逻辑查询

CREATE TABLE t(

a CHAR(5)

)ENGINE=INNODB;

INSERT INTO t(a) VALUES(‘a’),(NULL),(‘b’),(‘c’),(NULL);

SELECT * FROM t ORDER BY a;

//这也是一个小技巧,当想使用GROUP BY后,想统计各个组/块的数量,可以使用COUNT(1)

SELECT a,COUNT(1) FROM t GROUP BY a;

在这里插入图片描述

结果如上,很清楚可以看到order by会把值为null的排在一起,而GROUP BY会把NULL的规划在同一块上,也就证明了NULL = NULL。

所以Mysql判断逻辑会有三种表达式,TRUE、FALSE、UNKNOWN(UNKNOWN是根据情况为TRUE或者为FALSE)。

因此在产生虚拟表VT2时,会增加一个额外的列来表示ON过滤条件的返回值,返回值有TRUE、FALSE、UNKNOWN,会取出比较值为TRUE的记录,然后产生虚拟表VT2。

3、添加外部行

这一步只有在连接类型为OUTER JOIN时才会发生(因为只有发生外联结匹配的时候),比如LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN。在很多时候,我们可以将OUTER关键字省略掉,但OUTER其实代表的就是外部行,LEFT OUTER JOIN把左表记为保留表,RIGHT OUTER JOIN把右表记为保留表,而FULL OUTER JOIN就是把左右表都记为保留表。

添加外部行的工作就是在VT2表的基础上添加保留表中被过滤条件过滤掉的数据,非保留表中的数据被赋予NULL值,最后生成虚拟表VT3。

4、应用WHERE过滤器

对上一步骤产生的虚拟表VT3进行WHERE条件过滤,只有符合<where_condition>的记录才会输出到虚拟表VT4中。

在当前应用WHERE过滤器时,有两种过滤是不被允许的。

  • 由于数据还没有分组,因此现在还不能在WHERE过滤器中使用<where_condition=MIN(col)>,这类对统计的过滤,这也是因为顺序问题,聚合函数,是要进行聚合分组操作才会出现的,也就是GROUP BY,WHERE的执行顺序在GROUP BY之前,所以会报错Invalid use of group function

  • 由于没有进行列的选取操作,因此在SELECT中使用列的别名也是不被允许的,比如SELECT city as c FROM t WHERE c = 'ShangHai’是不被允许出现的。这是因为取别名,是返回结果的时候才进行的,也就是起码要进行SELECT语句后,才进行SELECT语句后面的字段,也就是别名c最早能被识别,是处理SELECT后面列的时候,但此时执行WHERE并还没有执行SELECT,所以别名c是找不到的。

CREATE TABLE t4(

id INT PRIMARY KEY AUTO_INCREMENT,

city VARCHAR(255)

)ENGINE=INNODB,CHARSET=utf8

INSERT INTO t4(city) VALUES(“ShangHai”),(“BeiJing”),(“HongKong”);

SELECT city FROM t4 WHERE id = MIN(id);

在这里插入图片描述

CREATE TABLE t3(

city VARCHAR(100)

)ENGINE=INNODB,CHARSET=utf8;

INSERT INTO t3(city) VALUES(“ShangHai”),(“BeiJing”),(“HongKong”);

//下面语句无法执行,因为c此时还没存在

SELECT city AS c FROM t3 WHERE c = “ShangHai”;

在这里插入图片描述

但以下SQL就可以成功执行

SELECT city FROM t4 AS c WHERE c.city = ‘ShangHai’;

在这里插入图片描述

这是因为FROM是最先执行的,所以可以识别出别名c的

此外,在WHERE过滤器中进行的过滤和在ON过滤器中进行的过滤是有所不同的,对于OUTER JOIN中的过滤,在ON过滤器过滤完之后还会添加保留表中被ON条件过滤掉的记录,因为后面还会进行OUTER JOIN保留表的匹配,但WHERE条件中被过滤掉的记录则是永久的过滤,即使在INNER JOIN中两者也是没有差别的。

SELECT * FROM t4 LEFT JOIN t3 ON t4.city = t3.city;

在这里插入图片描述

其实OUTER JOIN ON 其实是ON先处理数据,然后OUTER JOIN 补回保留表的数据。

5、分组(GROUP BY)

在本步骤中根据指定的列对上个虚拟表进行分组,最后得到虚拟表VT5。

GROUP BY要注意的点就是NULL = NULL(前面已经提过)

不过要注意的是,使用OUTER JOIN之后再使用GROUP BY,不太建议使用COUNT,比如COUNT(1)、COUNT(*),因为会把保留表的行也会加进去,导致数据不准

比如,这是t3表

在这里插入图片描述

这是t4表

在这里插入图片描述

然后进行下列SQL

//t4作为保留表

SELECT COUNT(1) FROM t4 LEFT JOIN t3 ON t4.city = t3.city GROUP BY t4.city;

在这里插入图片描述

结果显示产生4组,没组都有一条数据,这就证明了,t4保留表的QingHai在聚合时,独自分在一组

6、应用ROLLUP或CUBE

如果指定了ROLLUP选项,那么将创建一个额外的记录添加到虚拟表VT5的最后,并且生成虚拟表VT6。

对于CUBE选项,Mysql并没有实现,也就是并不支持CUBE操作,只是SQL中是有的。

7、应用HAVING过滤器

HAVING过滤器已经是最后一个条件过滤器了,之前已经经过了ON和HAVING的过滤器,HAVING过滤器是对分组条件进行过滤的筛选器,也就是对GROUP BY形成的块组进行过滤,后面的条件不一定是一个聚合,也可以是普通的条件匹配。

注意

子查询不可以用于做分组的聚合函数,比如HAVING COUNT(SELECT …) < 2是不符合的。

8、处理SELECT列表

虽然SELECT是查询中最先被指定的部分,即是顺序排在第一,但是直到现在步骤8才进行处理SELECT列表,这一步中,将SELECT中指定的列从上一步产生的虚拟表中选出。

先自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以扫码领取!

img

最后

金三银四到了,送上一个小福利!

image.png

image.png

专题+大厂.jpg
😕/img-community.csdnimg.cn/images/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />

最后

金三银四到了,送上一个小福利!

[外链图片转存中…(img-W5NxI0iv-1711403822378)]

[外链图片转存中…(img-1BAkrNVw-1711403822378)]

[外链图片转存中…(img-PCPxzSIF-1711403822378)]
需要更多Java资料的小伙伴可以帮忙点赞+关注,点击传送门,即可免费领取!

  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值