00:00
那go之后呢,我们来看一下这个叫having的一个使用having啊,在咱们写这个点的时候呢,提到过,说它的作用呢,也是用来过滤数据的啊,首先呢,我们把这个点写上啊,用来过滤数据的。那么这是它的一个作用了,那么咱们前边呢,是不是提到过过滤数据的话呢,咱用的就是where啊对吧,那现在呢,又杀出个程咬金说怎么还又多了一个having呢?那这里边呢,就跟咱们这个go by呢,实际上呢就有关系了,因为呢,咱们是不是讲完这个go by叫分组之后呢,咱们提到了这个having,那这里边儿呢,这个having的过滤啊,就跟咱们的grow by呢是有关系的,好,那这块呢,我们来看这样的一个需求啊,由这个需求出发呢,我们看看为什么要用这个having啊。这里边儿提到了说部门的最高工资比1万高的部门。这是一个需求,那这个需求的话呢,我们要想完成就得需要用到这个having来,我们用这个需求呢,给大家展开来说明。
01:00
啊,咱们这儿呢,就做一个这个叫练习了,说呢查询。各个部门中。这个最高工资。最高这个工资比是吧,1万高的部门信息。给部门信息,那部门信息呢,咱们就呃,相当于就是想查询一下这个各个部门以及他的这个最高的这个工资就可以了,Department ID max这个salary是吧?好,那我们这块呢,开始写一下,首先的话呢,提到了各个部门以及它的最高工资,那很自然的我们就会这样的去处理,首先呢,From employees没毛病是吧,然后呢,你可如说buy一下叫department ID,按照部门呢做一个分组。这块一方面呢,是我们解读这个题目呢,说得按照它分组,另外一点的话呢,大家也可以呢,就是叫什么流程化一下,什么意思啊,就是你只要看到在CY当中出现了这个,呃,这块呢,咱们下边呢,就会不加区分的把这个教程组函数,聚合函数,聚集函数,分组函数都可以,这个大家知道说的是一个意思啊,好,那么只要我们这个select当中出现了这个非聚合函数的话呢,这个字段就一定要出现在group当中,咱们上面呢,是不是都提到这个事儿了,这个大家一定要把它记准了。
02:18
那这样的话呢,我们一执行实际上呢,是不是就查询出来了,按照底盘呢进行分组,各个组的一个是不是最高工资啊。但是这块呢,你注意我们有一个条件呢,要求这个最高工资呢,看看哪些是比这个1万多的,那比1万少或小或等于的,我们就不要了,这时候呢,我们自然而然的相当于把这个过滤条件呢,是不是得呈现一下。那么以前呢,咱们写这个过滤条件的时候呢,那是不是只讲过用where,而且呢,说过这个大哥呢,是不是一定要紧跟着这个from来写呀?好,那自然而然的我们就想到了用威尔来处理,怎么处理啊,说最高工资比1万高,那你不就是想算一下这个所谓的最高工资。
03:01
就是这个salary是吧,Max salary,然后大于1万。是不是这个意思啊?行,那咱们写完之后的话呢,来一执行,然后呢就嗯没有然后了就挂了是吧,那这块呢,我们想强调的就是这呢是一个错误的写法。错误的写法就是这样写的话呢,是不对的啊,那这样不对的话呢,应该怎么去写呢?我们来一个叫正确的这个写法,这个正确的写法呢,是基于我们有这样的一个,算是一个叫结论吧。叫结论也好,我们说讲了一个要求也好,什么结论呢?就是说一旦我们的过滤条件当中出现了叫组函数或者叫聚合函数,那么此时呢,我们要求这个过滤条件就必须得用having啊来替换。好来我这块呢写一下说,如果过滤条件中使用了。这个呢叫聚合函数。虚函数,则这个嗯,必须使用,我们说叫having。
04:05
开,并来替换这个where。否则报错说的非常明确了,那我们现在呢,是不是出现了这个呃组函数了,或者叫这个聚合函数了,那你此时还用这个where呢,它就错了。那有同学就说说老师,为什么他就不让我们用呢?这个咱们先讲规则,一会儿呢,咱们来给大家讲这个为什么讲完之后呢,大家一定会非常的通透的,不管呢,你是这个笔试也好,面试也好,呃,这个大当然了,你要是个面试官的话呢,你是不是还可以去问一下面试的这个小伙说你怎么理解说必须要去替换。啊,我们说呢,编程语言或者我们这个SQ当中啊,有最基础的一些东西啊,其实这个大家不知道这个学编程语言有没有这种感觉哈,这个咱们先扯两句。不管你是学Java也好,学这个C语言C加加也好,还是学这个Python也好啊,还是学我们说这个GS也好,做前端的对吧,就是大家最初的在学这个编程语言的时候呢,实际上我们讲是有很多规则的,说要求你这个加号呢,表示的是加啊,也表示连接啊等等等等,这是一些特别底层的一些基础知识,这个呢,更多的我觉得大家呢,是作为一种规范出现的,或者叫规则出现的,你该记的记,该背的背,就是没有什么说为什么了,你也别研究为什么了,希望大家这个小的时候呢,学这个语言一样说见到他说你就叫爸爸啊,叫妈妈。
05:25
你总不至于说呢,说叫爸爸,你说我凭啥叫他爸呀,没有小孩会这样去想问题对吧,那就相当于是这个规则规范的,让你怎么干你就怎么干,然后呢,当我们这个知识啊达到一定程度之后呢,接下来的我们下边的一些东西啊,其实都可以用底层的这样的一些逻辑呢去解释的,所以说后来的东西啊,你也不用去记和背了,就是因为啊,所以去解释就可以了。那我们这块呢,学circleq也是一样子的,最初呢,我们讲的很多都是规则规范,那么以后的话呢,其实很多这个东西啊,我们是可以来解释的,那就是让你能够更通透一些,那这呢是高级的东西,诶这是高级的东西,它呢这种方法论呢,是可以迁移的啊,那这里边的话呢,大家就诶这个其实不是一个规定了,咱们一会儿呢,讲到这个circle口的一个执行过程呢,大家就会比较清楚,好,那我们先说先把这个事儿先说清楚,那么这里边要求来说,一旦呢,我们要是出现这个聚合,聚合函数以后呢,你必须要用having的去替换,好,那这时候咱们把错误的写法呢,我不得把它再粘过来,那自然而然的,这时候呢,相当于就要求呢,我们要用这个having并呢去替换了,对吧,那替换完以后呢,我们以为这样就OK了吗?哎,一直行啊,又化了,比刚才这个错误的还长。
06:35
这呢,相当于是对应的我们另外的一个要求。好,这块写要求吧。要求啊,其实这要求呢,我们是可以来解释的啊,行,那我写到这叫要求二,什么要求啊,就是如果我们出现了这个having的话呢,Having要求呢,得放在葛如BY的后面。这就相当于它的一个生命位置,注意,Having。开。
07:00
病啊,必须声明,在叫group by后面,你看这块呢,我都写的是这个大写,其实呢,你写成小写呢,当然也没有问题了,只不过呢,我们从那个规范上来讲,建议咱们这个关键字呢都大写,我这块呢也是起一个表率作用,大家呢,写的时候呢,也可以稍微的去注意一下这样的一个小的细节,那要求呢,Having呢,必须生命在go bad后面,那你现在写到前面了,它自然而然的就错了。那我们就放在这儿,然后把这个往上提一下,这个分号呢,补充上,这个是英文格式下的,行,此时呢,我们再去执行,终于呢,我们正确的答案就出来了。这呢就是咱们正确的情况,那一共有这么多部门,是不是满足我们这个题面的要求的,对吧?好,没有问题,这呢,咱们写了一个要求一,写了一个要求二。那基本的这个情况呢,那咱们就说清楚了,好,那接着这个点的话呢,我继续给大家讲一个点,这个呢,我们叫要求也行,或者呢叫一个规则也是。要求我这写一个三吧。什么呀?
08:01
嗯,大家想这个问题,咱们现在呢,说了这个having后边呢,这块出现的叫聚合函数,或者说呢,叫做这个组函数。那么问,呃,Having呢?还得写在go后面是吧?你说我们要是没有go的话呢,还能用这个having吗?没有。来大家想,我要是没有goodbye呢,意味着是不是就没有分组的,原来咱们这个分组以后,这个代表的是不是每一个组的最高工资啊,相当于是不是就每一个部门的最高工资谁大于1万,是这意思吧?好,如果我要是把group派给删掉了。我把格外删掉了,那自然而然的话呢,我们说习外当中出现了非聚合函数的这个字段了,那你格外又没有,那是不是这个字段也得给删掉呀。那么此时大家再看我们这个题面呢,是不是就退化成查询这呢,就没有分组了,那就相当于你是不是把整个公司的员工就当成这一组了,对吧?对这一组的数据求一个最大值,然后呢,要求是大于1万的,那其实呢,就相当于整个公司的是不是最高工资要求得大于1万了。
09:08
是这个场景吧,好,那我们选中了,先执行一下,大家呢会发现哟,也没有报错。确实没有报错。那这个max呢,为代表的就是唯一的这一组,就是整个107个员工这一组,那最高工资呢,确实是24000。那也出来这个结果了,但是呢,我想给大家强调的点呢,就是如果这种场景的话呢,我们这个再加这个having呢,其实意义就不大了。啊,怎么讲呢,你想想咱们这个having的话呢,嗯,或者我我换一个场景来说。你比如说我们现在呢,这个查询一个表,嗯,不管你是查什么,最后呢,我们查出来了多条记录,是这意思吧,那查询出来多条记录以后呢,我们说加个where说呢,我只想要这里边的某几条,说这一条还是这一条,你这块加个where条件去过滤就行了。是这意思是吧,那现在呢,如果说我们这个表呢,查出呢,就这一条记录了,我们其实就没有必要非得再去过滤它了,那你看一下这个是不是满足就行。
10:06
那放到我们这块呢,就是我们有了group之后呢,我们去分组,一分组呢,是不是首先有可能会有多个组,然后呢,你再看一下这个哪个组呢,是满足你的体面要求的,是这意思吧。对吧,那你得有分组,那如果要没有分组的话呢,是不是就只有一组了,那这时候呢,我们再谈这个having呢,其实意义就不大了。意义就不大了,我通过这个呢,想给大家强调的点,这也是以前有同学呢,会去问这个说老师呢,你看我把这个勾去掉,把这个去掉,我运行的也没错,这个怎么解释啊,那这块呢,首先说咱们在真正的去写这个工作当中写SQ的话呢,咱们这个having它的使用呢,通常都是依托于go。这我就是他的一个要求。或者这个这个比较要求了,也没有说非得强制啊,咱们也没看到报错这个呢,我们这样说吧,说这个开发中。开发中我们使用相当于having的这个前提。
11:03
是这个circle中。嗯,Circle中,那相当于他使用了这个格入和BY。哎,这个大家呢,注意一下这个点。那如果让你这个题面当中呢,没有这个group by呢,那一般的海病呢,咱就不写了。那我在这个课件里边呢,也有说到这个点,在这儿说happy呢不能够单独使用,必须呢要跟我们的go一起使用,这块呢说的非常的绝对了,那这块呢,你注意也确实是这个样子的。OK吧,好这块呢,大家注意一下啊,这个其实还也算是一个要求是吧,还是写成个要求三吧,这个跟这能够对齐。OK,那这个事儿呢,咱们就说到这儿,然后呢,咱们再往下去谈下一个问题。先把刚才这个呢,先弄清楚下个问题,我们刚才呢写了一个练习,是这个样子的,对吧?啊CTRLC1下来,我在那写个练习,这呢就要查询咱们公司中各个部门当中最高工资比一般高的部门信息,那我现在呢改一改说查询这个,嗯,部门ID为。
12:10
这个十二十三十四十,这。四个部门中。这个最高工资比1万高的部门信息,那我限定了只查四个部门对吧,那只查四个部门,那我们这块呢,该如何去实现呢。首先的话呢,我们相当于是不是在刚才做的这个题面的基础之上呢,光挑出来十二十三十四十这四个部门当中哪哪几个是满足的,对吧,那相当于这是不是也是一个过滤条件呀。好了,这也是过滤条件,以前咱们写过滤条件呢,像这个是不是都写在where当中啊,OK,那既然呢写where,那我们看看以前的这个思路来,那where呢,紧跟着这个from。那我们这块呢,就把这个where写在这个from的后面啊,Where depart。ID是不是in呀,十二十三十四十,诶这样子后边呢就不用动了,那么这样的话呢,对不对呢。
13:07
走一下子。你发现呢,是OK的。那也就是说呢,我们这样写呢,是可以的,没问题。这样写是可以的,这呢是咱们写的这个叫方式一。我这写方式一,大家就会想,那是不是还有一个方式二啊,确实如此。方式二,好,这个方式二呢,往哪块去想呢?大家你看原来呢,咱们没得挑过滤条件,只有where,现在多了一个having,那having有了以后呢,我们去想能不能把这个条件写在having当中呢?能不能写在having当中呢?那我们就试一把。我们把这个条件CTRLX,我在这儿呢,就来一个and了,后边一粘where呢,是不是就没有用了,来我们把它呢删掉。写完了对吧,写完之后的话呢,我们怀着这个忐忑的心情啊,就选中了去执行了,那意志行呢,还挺乐观的,发现也出来了,那言外之意呢,是不是就可以啊。
14:08
可以,那我们讲了这两种方式。这两种方式,那两种方式呢,我讲完之后的话呢,想必有些同学呢,心里边儿就有疑问了。你有什么问题要问的吗?有同学说有问题吗?如果没有问题呢,反而不对了,那说明你这块呢走神了,这块呢你应该有问题要问我了。什么问题?那我看看我说的这个问题是不是你的问题,那有同学就说说老师啊,以前呢,咱们讲这个where呢,后边填的叫过滤条件,现在的话呢,你就杀出个程咬金叫having,就having的话呢,除了咱们刚才说了有组函数的时候呢,你不让我用where行,那用having,那现在的话呢,没有组函数的也可以用开平,那我where脸面往哪搁呀?还有用吗?是不是这意思啊,这是一个问题,另外一个问题呢,就是说,呃,Where也行,Having也行,那么建议我们把这种条件是写在where里还是写到having里边呢?
15:09
这是不是也是一个问题呀?好,那么这个问题呢,我问完之后呢,我来替大家答,我就自问自答了就好,我就自问自答了。哎,大家呢,可以怎么着啊,你可以逆向思维一下。什么叫逆向思维啊,就是你从这个结论呢,你往回推,其实很多时候呢,都会是这样子的,包括呢,就是呃,相当于我们就是你。这个这个怎么说有结果往前去推这样的一种方式啊,叫一种逆向思维啊,由果所因是吧,你看呢,呃,我们说呢,叫存在就是合理的哈,呃既然呢,说到这个写法跟这种写法都可以,如果按照我们正常人的一个思路怎么着啊说where呢?呃,使用有局限性,里边呢不能够去写这个。这个聚合函数,那我们需要呢,换成heavy,这是它的一个局限性的地方,对吧,那么现在呢,就是你where呢,你不能放聚合函数了,那你放普通的这个过滤条件,发现呢,你普通的过滤条件呢,我们having也可以做。
16:10
那么如果说我们就此啊用的话呢,很多人就会想,那我这之后呢,就都用having就完了,我就不用where了,如果要是这样想的话呢,你看一下咱们在这个CIRCLE92语法当中,当时就已经有这个where和having了,那如果是这个where呢,这个没啥用处的话呢,那是不是一定会考虑在后续的这些版本当中就会把VR呢给干掉是吧?但事实上呢,我们没有把威尔干掉,至今威尔还活的好好的,那肯定呢,是不是存在就是合理的,那你从逆向往前推,既然它这个存在是合理的,那说明它还是有意义的,对吧?那还是有意义的,所以呢,我们就推出来一个结论,说这个方式一和方式二对比的话呢,我们推荐大家使用方式一。跟方式二比,那方式一呢,我们是推荐,为什么呢?因为它的执行效率高于方式二。
17:08
好了,那么把这个题目的话呢,咱们是先说清楚了,那相当于大家现在是不是又有一堆问号了,说你凭什么说方式一的这个执行效率就会高于我们这个方式二呢?啊,要想把这个事儿呢解释清楚,咱们就得看下边这个circle的这个执行的一个过程了,啊这个咱们等一下再说啊,咱先把上面这个呢,该想给大家表述的问题呢,咱先说完,然后呢,带着这个问号呢,咱们冲进这个第四个点。这块还有东西呢,没给大家去讲呢,咱把这个呢先补齐一下,哎,什么问题呢,来我们先把这个结论呢先上上去。这个结论是什么呢?哎,你先认可这个事儿啊,然后呢,我们再说这个结论,结论呢就是哎,我们说当过滤条件中。当这个过滤条件中,我们说呢,没有这个聚合函数时。
18:02
那就相当于是不是我们这样的条件啊,当过滤条件中,哎,先说有吧,有是必须的,当过滤条件中有聚合函数时,就是它,则此。过滤条件。则此过滤邮件必须声明在咱们的这个having中。这个呢,没得说。没得说。好,再接着当。当当什么呀?当过滤条件中没有聚合函数时。没有具有函数,那是不是就类似于我们这个条件啊,那要是没有具有函数呢,我们说则啊则什么呢?哎,此过滤条件。得此为条件,得此过滤条件,声明在外二中。Fair中或having中。啊,这个都可以。但是建议大家。
19:02
声明在这个呃,Where中。这呢不是这个这个同情啊,你说这个,呃,有你一个存在的理由吧,说呢,你要不就啥也用没了,那给你分一点吧,说你这个要有没有这个组函数的话呢,没有聚合函数的话,那就大家就用where吧,给人家一个面子是吧,可不是这个意思,这个呢,我写的叫建议,那对于大家来讲,你就别建议了,就是大家一定要这样去执行,也就是说呢,大家以后再写的时候呢,只要呢没有这个聚合函数,那一定用这种写法,就不要这样写,这样呢太low了。这样太low了,你要是去这个开发当中,这样去写了,效率会比较低,如果面试的时候这样写的话,那要我我肯定就是即使要你薪资呢,至少降2000。这个这个这个啊,连这个桥流的意识都没有啊。好,那这时候呢,我们结论抛出来之后呢,大家这时候呢,可能就关心说这个为什么在为什么之前呢,咱们再去多啰嗦两句,此时呢,咱们对这个where啊和这个having啊,咱们做一个简单的一个对比。
20:04
哎,在这我来写,说呢叫嗯,Where啊鱼。Having的一个对比。啊,这个呢,就是到面试的不咋会问,还是那意思,咱们开发中呢,要求大家去这样做,那对比的话呢,我们从这样的两个过程来说,首先第一个的话呢,从这个呃,适用范围上来讲。从适用范围上来讲呢,我们说这个having呢,是他完胜了它的这个使用范围,或者叫适用范围吧。这个更广。范围。更广这个怎么去理解呢?这个我课件里边这也有写,来我们看这它来对比,那第一个是吧,这就区别于我说的这个事,说呢having呢,可以完成where不能完成的任务啊,什么功能呢,是where无法这个完成的呢,就是我们里边有这个,呃,是不是涉及到这个,呃聚合函数了是吧。你要有结合函数的话呢,相当于是你必须要用having,没有结合函数话呢,Where也能做,这就是说它的这个适用范围更广,那我就不用多解释了,好第二点,第二点的话呢,诶或者第一个点的话呢,这个having呢,相当于是完胜,那从第二点的话呢,就是说,呃,如果过滤。
21:14
条件。是这个非聚合函数。哎,或者叫过滤条件中是吧,没有聚合函数。那我们说呢,这种情况下啊,下面这个where。它的一个执行效率。要高于咱们的海。啊,这个执行效率呢,要高于咱们这个having,相当于这里边我们抛的还是结论,大家呢,还是有这个问号在的,说为什么它高于这个having OK,那包括呢,你看我在这个课件里边有写这呢还提到了一个叫关联查询的问题,其实就咱们说的多表查询,在多表查询的时候呢,这里边又提到了这个V呢,效率也是会更高的,因为呢,它是先筛选后呢做的这个连接,而我们这个having的话呢,它是得先去做这个连接。
22:02
再去做这个筛选,那连接的,你像我筛选了再去连接,那筛选完以后数据可能会更小对吧?诶那从这个角度来讲呢,也是这个VR会更好一些,那这块呢,大家可能稍微有点懵,因为我们还没有呢去要强调比较多的这样的一些这个底层的这样一些操作,那我们在下边的时候呢,再丰富的给大家去讲啊。好,那基于我们刚才这样的讲法,呃,开发中呢,选择是什么样呢?就是他俩呢,是不是这个互相排斥的,就是不是这种竞争的关系,最后呢,就是说如果呢,你要是有组函数呢,有绝偶函数就用它,没有呢你就用where,这不就分开了吗?就是把他们两个呢,这个都发挥到这个性能的这个极限啊好了,那么大家呢,带着这个问号,我们下边来看一看这个SQ底层的这个执行的原理。那这个circleq底层执行原理呢,我们从两个角度呢,给大家去讲解,第一个呢,就是咱们书写的这个circle,这我写的circle其实咱们是一个查询对吧,就是我们自己书写的这个起来的语句,它的一个完整结构。
23:04
Select。语句的完整结构,诶这个呢,是我们要谈的第一个问题。那么我们这一章呢,讲的叫聚合函数,对吧,这一章讲完之后呢,咱们下一章呢,叫做子查询。这个紫查询呢,这个范范上来讲呢,其实没有太多新的这些操作了,那基本上呢,我们从第三章到第八章啊,就把这个select语句呢,讲的就算是比较完整了,子查询类似于什么呢?就好比是呢,大家如果你学习过Java呀,或者C语言的话呢,咱们讲了一层这个比如叫for循环,对吧,那循环里边有一些语法规则都讲完了,这个讲完之后呢,讲完之后的话呢,说诶大家呢,又看到一个新的问题,这个问题呢,发现一层for循环搞不定了,我需要呢,在一个for里边呢,再套一个for,那我们把这种呢称为叫二层for循环,或者说呢,叫嵌套for循环。那么严格上来讲的话呢,其实不算什么新知识的,你就是循环里边呢,又多了一个结构,把这个呢当成它的一个这个循环体就完了,对吧?呃,但是呢,这个结构呢,毕竟大家没有练过,属于说呢,呃,这个知识讲过了,但是比较难,那我们这个子查询呢,就类似于在查询当中又套了一个查询,这里就叫做子查询。
24:19
那相对来说呢,会难一些,但是呢,基本的知识点呢,咱们前面这块呢,其实都这个讲到了。那么到目前为止,咱们来看一下咱们的这个查询语句啊,大家能不能把它写完整了。我用一个这个多行注释。国王注释,好,那我们来看一看,首先的话呢,咱们讲的时候呢,是不是提到了一个select了,这呢,是不是就好多的这个字段了,那今天呢,咱们讲了这个叫聚合函数了,那有可能这个查询的语句当中是不是就存在这个聚合函数,对吧,你也叫组函数都可以,然后接下来的话呢,我们写这个from。上面的这些字段呢,有可能来自于一张表,也可能来自于多张表,我们这儿呢,就涉及到叫多表的查询,或者叫关联查询,那这呢,我们要写是不是就存在着不同的写法了?来我们在这标一下第一种写法。
25:10
或者呢,我们直接就写叫CIRCLE92的这个语法。在S2的语法当中,我们用这个逗号呢来进行这个。这个区分是吧,哎,就几张表。然后呢,紧跟着我们必须呢,要写一个where,在where当中呢,要指明叫多表的连接条件。连接。连接这个条条件好,那如果说呢,有三张表连接条件呢,我们说至少得有俩,你要这块少的话呢,就一定会存在笛卡尔基的错误,没问题是吧?好那么除了这个连接条件之外呢,我们VR还有一个作用呢,就是这个表示这个。叫什么过滤数据的啊,那这块呢,我们加一个案呢,就可以来体现呢,就这呢叫连系条件,紧跟着后边呢,就是所谓的叫过滤条件,这个过滤条件呢,我们说是不包含。
26:01
这个这个叫聚合函数的。过滤条件。条件。行,不包含具有函数的过滤条件,我们就生命在这个where当中。行,接着往下是什么呀。接着往下,那我们是不是该做这个格如何BY了格呢?就是我们说的分组操作啊,这个你看你有哪几个,呃,这个字段需要做分组的,那就go by写到这儿,然后紧跟着的话呢,我们是不是有个having啊,这个having的话呢,它是包含句合函数的这个过滤条件。嗯,写在这儿。还没完在后边呢,是不是我们叫order by了,Order by呢,指明这个字段,这个字段等等,我们可以呢,按照升序啊,或者呢是这个de,这个decent降序的方式呢,进行一个排序。进行一个排序,那排序最后的话呢,我们是不是还有一个limit。这个limit呢,我们可以进行一个分页的操作,这呢就是咱们整个的SQ92的这个语法行,那这是一个,然后呢,我们是不是还有一个叫SQ99的语法了。
27:07
来,我们把这个呢也写一下SO99语法,嗯,从哪变呢,是不是主要就这块儿,我们这块呢,要诶这个进行多表的一个查询的时候呢,我们使用的叫做John。啊叫做join,那join呢,完了以后呢,紧跟着我们后边呢,是不是就这个on呀,那on里边是不是就是多表的连接条件。多少连系条件没问题是吧,然后呢,有可能咱们是不是还有这这个多张表,那就再接着照再啊,哎就完了。哎,就可以了,然后呢,外当中呢,此时呢,它的这个就比较纯粹了,就是不包含聚合函数的过滤条件。不能包含就函数对吧,哎这样来去处理,后边呢,哎这个还这样,哎就完事了。哎,那同时的话呢,我们说这个SQL99语法呢,针对于咱们这个my circle,它还支持这个叫Y连接,那我们就可以呢,是不是叫left。没写错是吧,然后那个right。
28:02
嗯,那个for就别写了,因为咱们MYSQ呢,不支持这个for join我就不写了,那这个左I连接UI连接,然后CTRLC一下啊,这个呢也同样的道理。哎,习惯上咱们你像这个左外连接的话呢,呃,左表这个数据就多一些,然后把这俩要颠倒一下,呃,你相当于是你这个就就就跑右边了,就是相当于呢这个至至于说你是用左外还是用Y右外呢,主要看你这俩表这个在哪了啊,你要想把这个A表中的数据多,把它呢多查出来,你要A写到左边就得左外,你要A写到右边呢,数不据成右外了,所以习惯上咱们开发当中呢,你看哪个表的数据多呢,咱们就习惯上放到前边啊,那这样的话呢,咱们基本上就都用左外了是吧?哎,就这个小细节点啊。好,那么这呢,咱们把这个SQ92语法和SQ99语法呢,我就写出来了。哎,这个大家呢,得有能力自己来写,这里边儿这个过程呢,就是咱们编写的过程呢,是比较严格的啊,你就按照我这个要求去做了,这个完了以后,咱们下一个要谈的问题是什么呀,那就是语句是这样写的,那执行的时候呢,顺序也是这样的一个顺序从上往下吗?哎,我们说呀,不是的。
29:11
那下边我们要看一看circle这个语句的一个是不是叫执行的一个过程啊好,这呢是咱们的一个下一个。哎,我叫4.2叫circle语句的一个执行过程。注意这个我们叫它的一个执行过程。那这呢,我在这个课件里边呢,其实就有写。这呢是咱们这个算是编写的一个顺序,对吧,然后呢,这个执行那个顺序呢,跟咱们编写的顺序呢,它是不一样的,那这呢放了个图啊,这呢我又放了一个这个呃,这样顺序的一个方式,下边有点解释啊,其实呢,都是在说这个事儿。好,那这块呢,我就直接呢把它写出来。咱们直接写出来,大家注意听。SQL语句的一个执行过程是什么样子的呢?哎,这个我们为了大家方便的,我这样先画几个框。
30:01
这先框一下,然后呢。嗯,然后呢,到这儿。到这儿我再框一下,然后到这儿哎,我再框一下,相当于我框了三个框对吧,框了三个框,正常来讲呢,我们认为的这个执行过程呢,呃,感觉上它有可能是不是按照我们这个写的这个顺序呢,从上往下呢,就一条一条去执行了,对吧?但事实上呢,它不是这样子的,那它是怎么样执行的呢?我这样我标个123,这是一。哎,这个是二,然后这个呢是三,哎,我这样标完之后的话呢,我告诉大家的点就是说我们先执行这个一,然后再执行这二,再执行这个三,那一里边呢有好多条,那在一里边呢,它又是按照这样一个顺序的方式来执行的。这样一个顺序的方式来执行的。好,那我这块呢,就写一下子,写一下子咱们这样,哎,为了方便起见,我这块这样盯一下。大家方便看好了,那么首先呢,上来的话呢,咱们就先去from。
31:00
大家一想,我们现在呢,要查询了,假设呢,咱们就查询员工表和这个部门表,那我们首先呢,就先from from的话呢,你是不是这块有个表对吧?啊有个表,那下一步是什么呢?那我们说这个from之后呢,诶我我我就这么找一下啊实际上呢,哎,不管是你用CIRCLE99语法,还是用这个circle这个。还是用上面这个搜狗。哎,还是上面我们这个SQ92这个语法。啊,还是这儿,就是我们呢,先得从这张表啊找到一张表,然后呢,我们再找到另外一张表,此时呢,他们怎么着处理呢?呃,其实相当于是一个cross draw。实际上相当于是一个cross,什么意思啊,就是我们说的这个笛卡尔机。啊,进行进行这样一个交叉的一个连接,那连接完以后你不能这样整啊,这样整的话,这不是错误的吗?所以呢,紧跟着咱们后边呢,会有一个啥呀,就我这块讲的会更细一点,紧跟着呢,咱们不是有一个on吗。这个on的话呢,相当于就指明了咱们的一个连接条件了,对吧,那指明一个连接条件,那这个连接条件的话呢,是不是就把那些不应该关联的就给它去掉了,比如说我们员工表里边十,这个员工的一个department ID是十,那你跟这个部门表里边是不是就只跟那个十一样相等的去关联,不相等就不要了,是吧?哎,那这块呢,就是我们这个on呢,来限制的这个连接的条件。
32:19
好,那这样的话呢,一下子就会过滤掉很多的这个数据。注意我说的这个过程当中啊,其实存在着呃,叫什么一系列的,这个就叫虚拟表啊。诶,因为你看咱们最终呢,查完以后的这个数据呢,是不是就呈现在最后边儿,咱们本身呢,有一张表,可能还有一张表,然后查完以后呢,是出来这个结果,中间这个过程呢,它其实呢,你可以理解成就是这个虚拟表是来记录整个这个过程呢,然后每执行一步,这个虚拟表呢,就变换一下,每执行一步呢,就变换一下,最后执行完以后,它的结果呢,就是呈现在最下边了。是这个意思,好,那我们这块呢,有一个啊,就是这个根据你写的这个连接条件呢,就把这个数据呢,做了一个过滤了。
33:01
过滤完以后呢,这块还要注意一个问题,咱们有可能是左外和右外的一个连接,你比如说我们查询员工和这个部门的话呢,连接完以后呢,咱们只能够找到106个人,因为还有一个哥们儿呢,他是不是就没有部门啊,那这时候呢,我们还要关注一下诶,他是否是这个左外和右外连接。嗯,Right。哎,这个我这样写吧,John。这个大家能看懂吧。哎,这样处理的就是左或者右,就是你在这个填写完它这个关联关系之后呢,有可能用户呢,想要的数据会更多,你要是这个左外那这块我要考虑到左边的数据多,右边可能还要补一些这个no是吧,空的这样一些数据字段了,啊行,那就这样子,这个完了以后,相当于我们这一行呢就搞定了,然后接下来的话呢,是不是该这个where了,哎,接着该我们这个过滤数据。过滤数据,那过滤完以后呢,那我们相当于是比如说我只想要这几个部门的,那不是这个部门的数据我们就不要了,那外完以后呢,剩下这些数据呢,我们进行一个分组。
34:06
进一个分组,然后你告诉我呢,按照什么样的一个标准去分组,咱们分成一波一波一波分成好几个小组了,分成组完以后呢,接着咱们来看一下,你不是包含组函数的吗?你看你每一组里边你是最大呀,最小啊,还是平均的要求满足什么条件呀,那我们紧紧跟着呢,就是这个叫having。紧跟着是这个海好海完了以后,你想想我们现在呢,想分成好几个小组,然后呢,这个诶这个哪个满足哪个不满足,这个都已经都判断好了,接下来该什么了呀。我们说接下来该select了。你就说诶这时候才该select是吧?没问题,咱们这个select的话呢,就是本身咱们这个,呃,这个虚拟表当中,就是你在这个计算过程当中啊,其实这些字段呢,都考虑了,就是完整的字段,比如说你员工表呢,这就11个字段都在这儿呢,现在呢,你查询的时候,我们看看,有可能你只想查其中的某几个对吧,其他就不要了,那这时候呢,我们就还得过滤一下你不要的这些字段,那这个呢,就是这个select啊,我们来处理的,我只要这些字段。
35:06
好,那这块呢,相当于我们对这个列呢,又进行了一个限制,前面这些操作呢,你可以列解成是这个行数上的一些限制啊,一些过滤是吧?啊现在列上的话,我们只要这样一些字段,只列上的过滤,这个完了以后呢,基本上我们要查的这波数据啊,就已经确定好了。然后在下边儿呢,我们是不是select完了以后,哎,注意select这块呢,后边还多一个啊,叫做distinct。啊,叫做这个distinct是不是叫驱虫啊。因为我里边有一些数据呢,可能是重复的,那那select当中呢,你要是有这个的这个关键字的话呢,我们把这个重复数据呢,还得给人家过滤掉。啊,还得这个过滤掉好再接着,接着我写到这个下一行了。那过滤完以后的话呢,我们接着就该走最下边这个叫order by了。就相当于我们数据呢,最终都确定下来了,然后呢,你想按照哪个字段进行排序啊,你写一下这order,然后再接着的话呢,如果数据还挺多的,我们就可以让他去分页呢来显示,那这个呢叫做limit。
36:04
好,这呢,就是咱们整个这样的一个执行的过程,我就写完了这个过程,写完以后我说呀,我就能够给大家去解释,为什么我们说where的执行效率要高于having。好,大家看。比如说我们现在查询一个表,这个表中的数据呢有10万条。删条数据,好,我们先from这块走,假如就一个表,咱就不用照了,然后WHERE1上来这块呢,是不是就该过滤数据了,那比如说我们这个where呢,这个条件还挺苛挺苛刻的,我也没有包含这个组函数,我过虑完以后呢,我说就剩下十条。就剩十条,诶我就我就说比较少是吧,十条数据,然后你想十条数据里边,比如说我们按照这个部门来分组,诶我这就就两两个部门,那就这个十条数据呢,是不是就分成一个部门,再一个部门,然后呢,看看这俩部门,比如说最高工资怎么着啊一看哎呀这俩里边这个还不满足,是不是就只有这个满足这个我们就后边这个操作呢,就是做的事儿呢,就非常的快了,因为就这十条数据了。
37:00
你想想对吧,好,那如果说大家你看,如果你要是没有写where啊,把这个不包含具有函数的过滤条件,你要放在having当中,这个事儿呢,就很恶心了,这是10万条数据,然后呢,你没有where儿,然后上来呢,拿着10万条数据就开哧吭哧吭哧吭哧吭哧去分组,出完以后的话呢,一开病,然后还得比一下这个是不是大于这个,是不是满足满足满足,最后卡了半天,然后呢说就这几个满足,然后呢,紧跟着说来了个案子,说呢,我只要这俩部门的。前面这些都白做了。一顿分组,一顿判断,就是说我就根本不考虑。啊,太浪费感情了是吧,所以说呢,你要是不包括这个聚合函数这个条件呢,你千万不要写在这个heaven里边啊,跟着做了一堆无用功,效率很差嘛。那换句话说呢,它俩的区别在哪呢?就是我们这个where呢,就是它不用这个去分组上来呢,就每一条数据在便利的过程当中,一条条去取,我就直接给你判断哪个满足,哪个不满足,是不是就给你过滤了一遍。
38:02
而为什么我们这个where当中注意听,为什么外当中聚合包含聚合函数呢,就不能写在这个where里呢?那其实也解决这个问题了,因为呢包含聚合函数,这其实前提呢,我们说得有分组,你在这个你得分组之后。你看我们这个这在这分的组是吧,分组之后是不是才能使用这个分组函数了,你上来呢,就开始用分组函数,我还没分组呢,你咋用啊。啊,你说这是你,然后呢,你说我给这个给给自己。啊,这这个我我这这样说不合适啊是吧,就是哎在这儿来看啊,你这个having的话呢,你可以用前面的这个go by已经分组的,但是你这个where呢,你不是你不能上来就用我们后边这个操作里边的东西,就比如说这是你你不能现在给你这个儿子去借钱,前天呢,前提是你现在还没还没儿子呢,是吧,那你要是你在这儿的话呢,你可以给你爹借钱,因为。你爹肯定比你先出生是吧,就是你可以向前去借东西,去引用,你不能向后啊,这个呢,任何语言当中都有这个叫前向引用这样的一个特点。
39:01
这就说清楚了,哎,为什么它这不能放这个具有函数,为什么这块呢,不建议大家放,哎,不包括具函数的过滤条件啊就解释完了,那同样的话呢,大家回忆一下,我前面呢,在谈到一个知识点的时候呢,其实提到过这个问题,就是说我们在这个赖当中呢,是不是有可能会查一个字段,这个字段我起了个别名。哎,我起了别名。然后呢,我说一下这个别名啊,大家可以在这个order by中去使用。说不让呢,在VR中使用。那现在你知道为什么吗?你看我们select是不是在这块出现的,我在这块有别名了,然后呢,你是不是就可以在它的后边order by中去使用,但你不能在它的前边where中去使用吧,同样的是前项引用是吧?哎,这样的一个概念。没问题,好,这个呢,我们就把它呢,就给大家说清楚说透彻了。哎,然后呢,你看到这个课件的话呢,我这块还写了一个这个叫执行的一个原理啊,就是咱们刚才讲的这样个事儿,哎,咱们也提到这个虚拟表的一个一个意思了,就是每一个过程当中执行的时候呢,都是生成一个虚拟表,然后这个表呢,针对你执行下一个步骤呢,不断的进行这个迭代修改,然后得到我们最终要的这个结果集,对吧?那么哎,在这里边呢,写的就是首先呢,会进行这个比如说cross John啊这个得到一个虚拟表啊,这个virtual table是吧,虚拟表一杠一,然后呢,On呢,连接条件啊,把不要的呢,这个就不要了啊就去掉了啊VT1杠二,然后呢,这个根据是不是左Y右Y啊,还有全连接啊等等,然后这块我们得到啊一杠三这块呢,整体上我们就叫VVT1了啊,然后接下来呢,在where啊得到VT2,然后呢在go by和having啊,VT3VT4在select和distinct啊,V这个五杠一五杠二,然后再order by是吧,然后再limit啊,这就我们整个说的这个过程。
40:48
哎,我在这里边儿呢,都讲解到了。就讲解到了行这呢,就是我们说的这样一个执行过程,那么大家可能觉得说啊挺高端的是吧,哎,那么想给大家强调就是我们下篇讲的还会更高端一些,大家看我们这课件。
41:03
在下篇当中啊,我有一个章节叫做逻辑架构,好打开之后。这个逻辑架构呢,我们会谈整个这个数据库服务器呢,它的一个结构啊,就是这样的一些复杂结构,SQ呢,呃,接口,然后呢,解析器,优化器啊,这个缓存啊,这个我们的这个存储引擎啊,文件系统啊,日志等等这样一些结构,大家现在看的话呢,有点头晕,到时候的话呢,我们还会去讲这个SQ的一个叫执行过程,这个执行过程啊,咱们不是从这个语句出发了。那我不是从这个语句出发了,从哪儿出发呀,咱们从整个这个服务器的这个结构出发,什么叫查询缓存解析器是干什么用的,优化器是干什么用的,这个呃,执行计划又是一个什么样的东西,对吧?按照这个执行计划呢,我们去具体的操作了,包括呢,说这个存储引擎咱们也,呃前面提到过这个MYSM和这个度DB是讲count的时候提到过,那这又又是干什么用的,到时候我们把这个结构呢,也给大家说清楚。这样的话呢,整个S呢,不管是语句上,还是这个服务器的这个执行流程上,就彻底的弄清楚了。
42:05
啊,这呢就是偏底层的,那只有这块大家弄清楚以后,咱们是不是才可以再去谈circle的一个优化问题啊。就跟说你大家呢,你想养生啊,想养生前提呢,你是不是先得知道呢,吃的这个东西呢,在这个肚子里边呢,是怎么走的,这个这个哪个器官是干什么功能的,是吧?你吃的这个东西呢,就好比是我们这个circle啊,你得知道呢,不同的这个粮食里边,它有哪些这个营养成分,然后呢,你得知道呢,不同的器官呢,是专门干什么用的。啊,然后呢,你再呃清楚这些之后呢,你再谈这个养生的问题,这才能更接地气,而不是说呢,一上来什么也不懂,说养生书上说了先这么着再这么着,那你这样的话呢,学到的这个只是形而上的东西,你没法辨别他说的对或不对,就很很容易呢,被网上这个谣言呢,是不是所蛊惑,对吧。那就跟我们这块一样啊,你要是看到网上写一些色后优化12345,你上来就一顿背,那其实里边呢,不排除有一些是错误的。
43:04
或者要至少是不准确的,那怎么才能使你具备这个辨别能力呢?那你就得有这个完善的一个底层架构,那就相当于是你得知道这个circle呢,它是怎么回事。对吧,诶你得知道呢,我们这个底层这个服务器这块呢,它执行的是个什么过程,然后呢,你再看这个SQ的优化才能够非常的清晰,这样的一个流程更接地气,面试官要问怎么问都不怕,你甚至是不是还可以反过来去问他呀。啊,没有毛病啊,这块呢,也给咱们这个下篇啊,咱提前做一个广告,OK行,那么至此的话呢,咱们把这个说完之后,至少在咱们这个上篇当中啊,咱们有很多问题啊,其实就迎刃而解了,大家呢就比较清晰。对吧,为什么说必须要这个,哎,必须要写在这个这个里边是吧,哎这些呢,我们都基于这个过程呢,是可以做这个解释的。好,那么我们关于这一章的这个知识层面呢,咱们就说到这儿。
我来说两句