00:00
好,那么接下来呢,看一下我们的第八个需求,这是。交易下单各窗口的汇总表啊,那在这个需求当中呢,我们要干什么事呢?要统计当日下单独立用户数啊,以及新增下单用户数,那其实跟我们上面这个需求啊。支付这个需求有什么区别吗?大家大家感觉到。没有吧,那我们是不是还是对这个数据要考虑做一个去重啊,当然因为由于咱们求的是这个用户数,我不做驱虫其实也可以。对吧,咱们不去做这个驱虫其实也可以啊,这个事我们都分析过了啊,驱虫的方案呢,123都有对吧?啊这个里边呢,我们还是通过啊,还是通过这个。窗口。啊,不是窗口,就是我们的状态来做的加定时器,对吧,这里边儿我们写的是这个,但是呢,我们就。
01:06
换一种吧。OK了啊,咱们呢,换一种。啊,咱们换一种对吧,好,呃,咱们呢,嗯,你要按那个写也行,换一种呢,就更简单一点。啊,换一种就更简单一点,就换什么呢?换我们的这个。保留第一条数据。啊画我们保留第一条数据,因为在这个里边呢,我们除了求这个呃,独立的用户数。就行了,诶这里边刚才我们看到。独立用户数,新增用户数,除了这之外,这个忘了写了,呃,我们还把这三个金额可以。给它放进去,当然你不写这个其实也可以啊,呃,那就涉及到我们得考虑一个问题,因为我们要换这个去除方案的话。啊,如果咱们要换这个去除方案的话,对吧?呃,那就涉及到这几个字段。
02:07
啊,那么这几个字段。咱们。是要取最后一条。还是说?第一条就够。对吧,啊呃,首先呢,我们先聊的,如果我们只求这个用户数。那么可以去除,也可以不去除。对吧?呃,如果加上另外的数字金额啊这些东西,那就必须要做去重,那在我们必须要做去重的时候呢,其实我们有多种方案。可以选择对吧,那一二呢,肯定是通用的,因为它保留是最后一条数据,那你要什么字段都可以,对吧?那么第三种方案呢,是说当我们不需要left draw右边。表数据里边的内容,我们就可以用第三种,我取第一条对吧,那我们来看一下啊,这里边呢,要的是。
03:04
All activity reduce amount,就是说活动的减免金额对吧?呃,然后呢。勾券减免金额,然后还有一个原始的总金额。啊,咱们还有一个原始的总金额。对吧?好,呃,那这个咱们就要注意一下了,这个原始总金额大家还记得吗?是拿着我们的SQ number乘以all price2个得到的一个数据。对吧,因为之前呢,我们在DWD文档当中的D已经做了这个处理了,而在我们自己写的那个里面并没有我把那个字段都干掉了,我说了可以不保留,对吧,因为我们所加的那些字段呢,都是通过原有的字段。做出来的。啊,所以呢,我们只要保留最原始的最根本的这个字段,到了未来你想要什么字段都有,对吧,前期呢,其实可以不要,可以不要,那这个字段呢,我们就不用考虑了,对吧,直接SQ number乘以这个price就好了。
04:09
关键是在于这个呢。这个看上去跟活动还有这个。优惠券它有关系呀,对吧,那我们就看一看all info跟这个all the detail里边有没有这两个字段。对吧,好。那这个是all the detail对吧,接下来呢,还有一个all in for,我们打开all in for里边呢,我们来看啊。他有没有那个。自带呢?诶,他是。有的对吧,只不过说你看这个参加了活动就有对吧,否则呢,它是零。它是零对吧,哎,也就是说它并不需要。从我们的。这个。
05:01
Activity,或者或者说这个卡这张表里边儿去拿。对吧。不需要啊好,那all the detail里边呢,我们来看一下啊,它有切分。之后的。总金额。对吧,然后呢,这个是切分后的。参加活动的减免金额对吧,参加活动的,那这个是什么意思呢?那也就是说,那我们想啊,到底这几个字段啊,这有一个or total Mo对吧?啊原始的金额,然后呢,这个是活动,这个是卡本减免的,那我到底要用哪个呢?要用all in for还是用all detail里边呢?因为它俩都有啊,对吧。金额,那我到底应该用谁的呢?你应该用谁的,大家告诉我。就是假如说两边我们都保留着,对吧,就是all in for跟all the detail两边都保留着,那我们应该用谁呢?就是你要体会啊,业务业务上这两个,比如说啊,它叫split total amount跟这个total amount它俩的区别在于什么?
06:19
你要了解到它俩的一个区别,你就清楚了到底应该用哪一个字段,对吧?到底是用out in for里边的,还是用all the detail里边。有同学来说一说,它们俩有什么区别吗?啊,不知道吗?这两个之间的区别就all in for跟all the detail里边的区别不清楚吗?
07:07
来,我们说一下这个。呃,这个是这样子的,因为我们一个订单呢。一个订单它可能对应多个订单明细,对吧,1001。A。1001。B。对吧,好,那明细呢,我买了A商品嘛,买了B商品,比如说啊,他呢买了三件,他呢买了两件啊他呢是一件50。可以吧,一件50啊,总共呢150。啊,他呢一个75啊,买了两件总共呢也是一百五啊,那刚才我看到了原始的一个总金额呢,那就应该是300。而在两个明细里边。都是一百五好,那我呢,可能这里边儿参与了一个。活动。
08:01
啊,他呢参与了活动,他呢也参与了活动,比如说他参与了活动呢,减了十块钱,他呢参与活动也减了十块钱啊,那对于我们整体order info里边,那么我参与活动减免的金额呢是20,那分别呢,他俩都是。十。能明白吗?就是他俩呢,只不过说,因为我们看到的这out in four里边是总的嘛,对吧,你你应该付多少钱,然后减免了多少钱,对吧,把这个扣掉啊,那么这边呢,就是切分后的spli的total amount split activity amount,就是把针对于每个商品给他。拆开的这种。能明白吗?这就是业务上他们俩的一个区别哈。它们俩的一个区别啊,那按照这样来说的话。对,商品分摊没毛没毛病啊。好,那按照这样来说的话,呃。咱应该用哪一个,就是我们这个需求,我们应该用哪一个呢。
09:03
我们应该大家觉得我们应该用哪一个。咱们应该用哪一个。对,很明显咱们要用的是这个order。Detail这张表吧,啊,用的是这里边儿的字段,因为它呢是总的。啊,他那是总的,也就是说什么意思呢?比如说刚才我们举个例子,对吧,1001啊总金额呢300,优惠呢20对吧,最后一个呢是那那我们就看这个活动呗,对吧,他拆成了两个明细,1001A1001。B,呃,你把这两个数据关联起来的时候,你像这个300。
10:02
20,那20这个是有的对吧,那他同时还有一个150。然后还有十。对吧,哎,他是这样的数据,那我们要的肯定是他,哎对吧,总金额,最后你要做累加,你肯定累加这个你不能把订单的金额累加呀。一个订单对应多个订单明细,你要直接对订单进行累加,你不完了吗?是不是?对吧,啊好,所以呢,这块一定要注意一下,那我们就要搞清楚了,第一啊,呃,咱们呢,发现原来的out in for或者out当中确实有我们要的这个。字段啊就够了,对吧,也就是说并不需要activity或者carbon这个表的一个参与啊,这是第一个对吧,它是不需要的。啊,它是不需要的,那也就是说我们去重方案呢,可选第三种对吧,虽然你要做驱虫,但是呢,可以选第三种,这是第一个,第二个就在于我们看字段的时候发现有两套,对吧?All in for里边有关于这么一套金额的,像all detail里边呢,也有一套关于这个金额的。
11:04
啊,但是我们通过分析发现呢,按照我们join起来以后再做聚合的话,我们肯定要用all the detail这里边的一个数据,对吧,我们要用的是all detail里边的一个金额数据,对吧?啊,因为最后呢,我们肯定要做一个转化为类似于这种招病,当然这刚转换的时候,他俩呢。他俩肯定还是什么,给个空就行了,对吧,给个空啊就行了,对吧,这是我们。看到一个点。对吧,啊,那这里边呢,我们就用呃,第一条数据的这种方式做一个去重,也就是我们第三套方案对吧,第三种方案我们取第一条数据进行输出就够了。啊,对于这个订单明细而言,我们取第一条数据进行输出,OK吧?啊,因为我们要的字段呢,无论是第一条还是最后一条,它都包含了我们所需要的所有的子段了,啊,那我们就取第一条就够了,对吧?好,呃,这是我们整个的一个需求分析,那后面呢,就是正常的题转化为这个招病以后。
12:08
转化为这个招聘以后,接下来呢。就直接可以开窗聚合了呗。对吧,直接开窗聚合就好了,OK了啊,这是我们整个这个内容啊,接下来呢,这是思路整理,然后呢,我们稍微的快速过一下啊,因为刚才我们已经聊了这个事儿了啊,就细节的东西,就关键点跟之前需求不同点,跟大家聊了一下,对吧,首先消费这个订单明细主题数据,就下单主题的数据对吧?呃,接下来呢,处理成结算格式。啊,好。呃,你要害怕有那值的话,你可以还是一样的把这个过滤掉啊,把这种非阶层格式数据过滤掉,接下来呢,按照违建凹的低ID分组进行一个去除。对吧,进行一个去拢,当然这里边我们所写的还是状态的那个时间啊,按照这个进行比较,但是呢,我们其实可以不做这个事,我们直接就要第一条就行了,对吧,来了之后如果状态为空,那我呢把它写出去。
13:07
啊,如果状态为空,那我们把这个数据呢输出对吧,如果状态不为空,那这个数据呢,我就不要了啊,而且由于上游呢,咱们。Join的这个过程。对吧,给了五秒钟的一个时间,那么在这个地方呢,我们也可以设置TT2为五秒或者十秒,你保存多一点,这个没关系,你多保存一会儿,因为它不影响我们数据的输出,对吧?我们可以多保存一会儿,我只要第一条,对吧?哎,我只要这一条的话,我只要all detail ID第一条数据。对吧,所以呢,我们在这也可以设置一个TTL,没毛病吧,啊,就跟我们在之前的方案里边设一个定时器是一个道理。因为你数据呢,我能保证他能在五秒之内全部到齐。对吧,那我定义一个五秒的定时器也可以啊,这个无所谓对吧?啊,大不了呢,你把它写成这个right read and write,就是被读了之后你重置一下,那总总总没有问题了,对吧?好,这是我们等会换一个期中方案啊,这是我们要换的啊,文档当中呢,我们两个写的是一样的,但是呢,希望给大家看一下更多的一些方案嘛,对吧,也可以用这种方案来做一个驱虫,好呃,那去好虫以后呢,我们就可以干什么事。
14:22
按照这个。UID进行分组了,因为我们要取这个独立的用户数。对吧,取这个独立的用户数啊呃,那取的时候呢,还是一样,先判断这个状态是否为钠,如果它为钠。那直接两个都是一。对吧,哎,当天的唯一。新增的也为一啊啊,那如果不等于呢?那接下来看于当天的时间是否相等,哎,如果不等对吧?注意这有感叹号,如果不等,那么当天为一,总的新用户为零对吧?如果它俩相等,那么两个都是零。
15:02
两个都是零啊,然后呢,封装成一个招聘把它写出去。对吧,把它写出去,但这个招聘封装的时候,我们还有几个金额要提取对吧?呃,这个时候你不要,诶两个零我就不要了,这个不对,就算你这个对于用户,他不是一个新用户,但是你的订单金额得算。金额得算对吧,所以呢他呢是不需要判断这个两个零的,能明白吗?这一块就是以前我们所有的关于这种需求,我们是不是都做了,哎,只要你俩都等于零,我这条数据就不输出了。对吧,但是对于这个需求而言,我们不能这样干,因为除了两个用户数以外,我们是不是还有金额呀。那你用户数可以两个是零,但是我金额它不可能都是零。不可能三个金额都是零,那你这个下订单也就太离谱了。对吧,你用拼多多,你得也得花一毛钱或者一分钱抢什么东西呢,对吧,他没有说。
16:04
不付钱抢东西的吧,有吗?我好像没遇到过任何这个电商平台,他可以几乎免费,就是你象征性的付一毛钱或者一分钱,对吧,但是说。不要钱的有啊。没有吧,对吧,就算不要钱的有,那总还有一个原始金额吧。大家说是不是总还有一个原始金额对吧,你原本值多少钱,那总得有了对吧,只不过说你采用了各种优惠券对吧,然后呢,最后呢,不花钱啊,但是呢,他总有个原始金额吧,他不可能这个商品从原始就是不要钱。对吧,那不可能啊,好,那这个地方是我们要注意的,跟前面需求有所不同的,对吧?好,那这个做完之后呢,正常的就是。啊,开窗聚合对吧?啊,这边说了其余度量字段直接从流程数据取对应值即可,但是咱们呢,稍微的加工一个就是那个original对吧,我们要乘一下,因为我们之前一直在强调的是我们前面呢。
17:09
好,Info当中我没有加对吧,那个预处理表当中,我把那些字段呢,额外引申的字段我全都干掉了,对吧,我只保留了最原始的字段。啊,但是今天上午呢,我们加了一个就是数据的时间对吧?好,那到这一步开张聚合呢,就比较简单了啊,都是写过的,最后呢,把数据写到这个click house里边也没什么好说的,对吧?啊所以呢,咱们里面这个点就在这驱虫,我们换一种方案,第二个呢,就是这边度量值它不一样了,处理方案不一样了,OKOK了啊。好,那接下来呢,我们完成我们的这个整个代码啊,第一步呢,先把我们的这个表啊,因为我们科里老师开的嘛,所以呢,我们就从上往下把这个表呢,顺手去创建一下,对吧?好,那接下来第二个。
18:01
呃,构建我们的扎并叫trade的凹并啊,那还是我跟表一样的字段啊,还是跟表一样的字段啊,好,那直接。拿过来。啊,在并包下再创建一个扎病啊,那把这个直接拿过来啊,还有我们这些字段。嗯,那两个窗口信息,五个度量值,因为两个用户数嘛,三个金额对吧,然后加一个。啊,那总共八个字段啊,这个这个需求呢,有八个字段啊,那接下来呢,我们就可以到APP里边去写我们的核心代码了啊嗯,这个类名呢,我还是拿一下啊。好,还是一样的,在这里边儿呢,我们先把我们要做的事情的思路先写上啊,因为这样的话,接下来就相当于我们往里面去添代码,这样就会方便很多,对吧?呃,第一步。
19:02
获取执行环境。啊,那么第二。读取。卡不卡?这个DWD层。下单主题出具用来创建流对吧,好,那第三步。那当然是将咱们的。数据转化为切对象。对吧,转化为这个杰森对象啊呃,当然这个里边呢,你加一个过滤也可以对吧,还是一样的,你把这种非杰森的给他干掉啊,你要简单的做一个打印就行了,对吧?好,那转化为接对象以后,那我们就要做第一次的驱重了,根据all的detail ID做驱重对吧?好,那就是按照这个叫什么呢?All。
20:01
Detail。ID分组,按照它进行分组对吧,分组以后呢,我们去重。好的ID。静心去宠。对吧,这个去轴呢,我们。选用的方式保留。第一条数据即可。我们只保留第一条,其他的呢,我们就都不要了。啊,是这样的方式对吧,好,那接下来呢,是我们的。第六五啊,那这一步呢,相当于我们已经去好重了,哎,每个凹的detail ID呢,只有一条数据会往下游发。啊,会往下游放对吧,好,那这个搞定以后呢,接下来我们要考虑提取。下单用户数了,还有一个新增的对吧,还有一个每天的一个新增的啊呃,那提取这个之前呢,我们先提取事件时间生成。
21:11
好,那这个呢,我们都可以做一下对吧?嗯,第七步。啊,第七步就是。按照。UID3组。对吧。那这一步呢,提取独立下单用户。啊,当然这边包括两个,一个呢是每日的,一个是呢总的对吧?啊,当然除了这个之外,还有这个金额啊和金额对吧,金额呢,我们需要稍微的去加工一下啊,稍微加工一下OK吧,啊,那这个东西已经搞定了,搞定之后呢,它就转成了我们这个对象了吧,叫trade all b这个对象对吧?啊这一步呢,还是用一个。Friend map,而且呢,用rich这样的方式来做啊。那第。
22:01
九步。啊,那第九步就是你已经变成招聘了,我们就开窗聚合了。开窗聚合啊,那么最后。第十步。将数据写出到。启动任务。对吧,这是我们整个的一个需求,在这儿,就是整个的思路也比较明确,对吧?啊,整个的数据都下来的啊,那么第一个获取执行环境。诶,这有对吧,拿过来往这一放。这第一个啊,第二个读取这个来创建我们的流,把它拿过来。小妹。好。
23:00
ADD source啊,然后呢,叫my cover consumer。卡尔加得到一个卡的一个DS。对吧,这样呢,得到一个流,这个东西呢,也写的比较多了,接下来呢,我们要转成这个接送对象,好把第二点。呃,那这个地方呢,我们用这个过滤过滤加这个转换对吧。啊,那我们就创建一个map啊。好,那这里边的写法呢,呃,跟之前一样,我们再写一次啊。省点pass object value。那正常的呢,我们就直接out.connect杰就好了,但是呢,它有可能会出现这种非接格式数据啊,只是做一个保险,其实到这块呢,已经不会出现了啊呃,做一个保险呢,开始掉对吧?开始掉以后呢,我们把这个数据做一个打印啊。
24:05
当然你随便加点前缀,生态环境当中呢,你可以用测殊流把它写出去啊好,那这个就搞定。对吧,这一步转换为这个对象就搞定,得到一个切上OB接的一个。DS,对吧?JS对象啊,呃,接下来呢,按照这个all的detail ID进行一个分组,那咱们的替代啊,这里边呢,已经是接格式了,所以我们写杰森,那接下来我们去拿一下,嗯,它的一个all detail ID在这张表里面到底叫什么东西对吧?我们找到all的detail这张表啊,我们因为消费的就是这个主题,对吧?呃,拖到我们的最后。啊,拖到最后在这边。对吧,在这边好,那么。这边呢,我们all的detail ID在里面叫什么?就叫ID,是不是没有取别名啊,就叫ID对吧,拿过来啊,呃,那这个地方呢,我们就是杰森。
25:01
点get string啊就叫ID,那这个就简单了,看加倍得到一个key的。BY。这个detail。ID的一个。对。Data stream对吧,啊by detail ID明细ID,那这一步呢,就搞定了,就搞定了对吧。好,那接下来呢,我们要保留第一条数据做一个去重,那这一步呢,其实比较简单了,对吧。电。呃,那很明显呢,咱们保留第一条,那很明显它是一个过滤对吧,我只要第一条后面来的呢,我都不要了,所以呢,我们直接写一个。呃,再加上呢,我们要保留第一条,那后续来了之后,我得知道有没有人来,所以要用状态编程对吧,所以呢,我们有一个这个rich felt。Function。对吧,好就这样子的,好,那这里面呢,我们搞一个数据表示他在还是不在就行了,对吧,随便存一点东西,只要他不是弄就行了。
26:09
只要不是none那就够了,随便呃,你存一点东西都行,对吧?啊这个呢不重要啊好,那我们这边写private state。String对吧,好,那接下来呢,在这边我们写一个。Value state,它就是表示是否存在的,你叫is exist也可以对吧?啊,都无所谓啊,这个地方呢,只要你随便给一点东西就行,因为我只判断它是否闹来决定,我不看它具体的值,它具体值跟我没关系,对吧?只要你不等于闹,说明有人来过,只要你等于闹,说明之前这个订单。这个订单明细没有来过。对吧,没有之前没有过数据啊就行了,所以它就是起到一个表示前面有没有数据来啊,好value this,呃。
27:00
Get wrong get,哎,这个呢,咱们既然说了,我们可以给一个时间对吧?嗯,另有一个。TT。Con。对吧,啊,还是点build。点build啊,当然了,你如果说不放心的话,你加一个这个update。点on read and read对吧,那这样的话看一下就能多保留一会儿啊,这里边时间呢,咱们给一个五秒钟其实就够了,对吧?啊,前面呢,我们都给了五妙度啊,所以呢,这边呢,我们也可以给我妙度time点。Second,来给一个五秒钟对吧。呃,那这样的话呢,CTRL加V我们就得到了一个TDL康菲啊,那接下来我们就可以。一个叫state。啊,这边呢,就是表示我们的意思exist。随便啊,这个名字你随便取啊,就是你多个,你如果一个程序当中你有多个地方用到了这个状态,你不要取一样的名字就行了,对吧,至于这个名字叫A叫BB啊,都无所谓啊好那。
28:12
点。Class。啊,那我们就得到了一个描述器,对吧。不要这么长对吧。就叫stay描述器啊,然后呢,给它点enable time to live对吧,T dl conflict给它放进去啊,嗯,给他设计进去之后呢,把这个。描述器给它放进来,那我们这个状态就。有了对吧,我们状态就有了好,那么接下来这边我们怎么做呢?很简单,来啊。获取状态。数据。对吧,嗯,value.value。啊,那我们就得到了一个状态啊,然后判断状态是否为呢。
29:03
If stay。如果等等于那。啊,如果等等于呢,那返回的就是处。对吧,最终呢,我们就返回处啊else。否则咱们返回的是什么呢?返回的是false。对吧,但是还没有结束,如果你这样的话,那你所有数据都是出了,因为你没有改这个状态值啊。对吧,所以在这里边注意啊,这个valueate.update随便吧,给个一对吧,表示已存在,那么你同样的out I如果来了。再来一条,那么我是不是已经是一了,我就不等于那了,不等于那呢,这个数据直接被干掉了。直接被干掉了,而且呢,每来一条数据都会读这个状态,对吧,读状态呢,它又会重置五秒钟,那挺好的,这样就循环起来了,对吧,直到最后一条奥基ID来过以后,这个呢,这个状态就不会再有人读了,它再过五秒是不是自动就没了。
30:04
这个状态自动就没了,对吧,他也不会永久的一直在这存着啊,也不会占用我们很大的这个状态的空间,所以呢,我们要记得用到状态的时候,你就想这个状态能不能晒。对吧,如果能删,你就考虑第一个呢,我们可以用TTL,第二个呢,可以用这个定时器去删,这个状态能理解哈。好,那这块呢,咱们的过滤就写完了,对吧,我们采用的是保留第一条啊,当然这个并不是严格意义上的第一条,其实如果你这个这能这样写啊,我们都没有考虑乱序对吧?都没有考虑乱序,那这种写法呢,注意是因为它不需要left draw右边表的数据,所以呢,也不是说取第一条吧,就是取任何一条就行,那我为什么写第一条呢?这个第一条指的是什么?就是考虑上乱序,谁先到这里的,我不管你是不是真的,你第一条产生的,我不管,我不考虑你的产生顺序,对吧?我只从处理时间的角度来考虑,你是第一个到的,我保留你就够了,因为所有的假如你有五条数据对吧?你关left join了四张表,你呢,最终可能会有五条数据,那五条数据里边一张来的招的表,我都没用到这个字段,那我只要最原始的那个字段。
31:22
对吧,那此时呢,我们就直接干什么,保留任何一条都可以啊,就是任何一条都可以对吧。好,CRV,这样的话我们就得到了一个felt点,诶过滤后的一个数据这块大家有没有问题。没有问题,给我扣个一好吧。这一块我们所写的。啊,因为大家分析过了,他呢没有用到我们。右边表的字段对吧,那我任取一条都可以啊,所以呢,我就按照过来的顺序保留第一条。
32:06
好,这个就解掉。
我来说两句