mysql sql执行顺序的理解

比较复杂的SQL可以拆开,拆到最小全量结果,中间结果就一目了然了,然后就方便理解了
select a.s_id from Score a join Score b on a.s_id = b.s_id where a.c_id = ‘01’ and b.c_id = ‘02’
分解步骤:
a. Score a join Score b on a.s_id = b.s_id
在这里插入图片描述b.where a.c_id = ‘01’ and b.c_id = ‘02’
在这里插入图片描述c.select a.s_id
在这里插入图片描述21、查询不同老师所教不同课程平均分从高到低显示
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述总结:
1.join通过on关联字段得出中间结果集,然后再通过中间结果集一步一步过滤
2.最后过滤出你要的结果字段值,不要考虑其他字段结果是否正确
3.用a.,b.,c.*可以看到所有的结果集
版权声明:本文为CSDN博主「Felix.Yip」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_42115021/article/details/85396405

2、案例2

假设现在有一个用户活跃表t_active,记录了每天活跃的uid和相应的活跃日期。现在想要看距离某一天日期差为0天,1天,2天,3天…活跃的用户在当天还有多少活跃(也就是一个留存的概念)。期望得到的如下表所示:

在这里插入图片描述
对于表中数据,我们可以这样理解。距离2019-09-29 0天(也就是2019-09-29)的活跃人数为100,2019-09-29当天活跃的还剩100,距离2019-09-29 1天(也就是2019-09-28)的活跃人数为80,2019-09-29当天还剩60。以此类推。

对于这个需求,我们可以使用left join进行自关联,用之前活跃的天作为左表,最终期望计算的天作为右表,计算日期差,并进行左右表分别计数。初步的SQL如下:(数据是自己编的)

在这里插入图片描述
在往下看之前请确认你理解了需求目标,并先思考下,以上的写法有问题吗?能否得到上面期望的结果?

原始数据和这段SQL运行的结果如下:

在这里插入图片描述
运行结果中出现了dt和datediff为null的情况,你能想象的到这是为什么吗?而且当dt不为null的时候,最后两列的数据是相同的,显然和我们的预期不符。这是什么原因呢?我们来逐步看一下。

首先,我们使用left join 的方式应该是没有问题的,我们先看看不加任何计算的,select * 的结果是啥。

image
可以看到,这相当于是前文提到的不加where 条件的一对一关联,结果会以左表为准,关联不上的用null补齐。值得注意的是,关联不上的日期是null值,而null值在参与datediff的计算时,结果会是null。到这里你是不是明白一点了。由于null值参与计算,导致最终datediff 有null值,并且计数的时候,由于null值存在,最终用日期差作为维度的时候,导致左表和右表的数量是一样的。如下面代码所示:

image
从上面的结果我们可以推演出最开始的SQL运行结果。例如,datediff=5的时候,共两条记录,左表右表的count(distinct uid)都为2。datediff为null的时候,左表结果为7,右表为0,其他的以此类推,和前面的结果是一样的。这样我们就知道了,没有达到预期的根源在于存在空的日期。那么怎么解决这个问题呢,显然就是把空日期填补上就可以了。可以使用case when 当右表日期关联不上的时候,用相应日期补足。代码如下:

image
可以看到最终得到了想要的结果,以最后一行为例,它表示,距离2019-09-29 5天的那天(也就是2019-09-24)活跃的人数有5个,那些人在2019-09-29仍然活跃的有2人,你可以看一下明细数据核对一下。其余的以此类推。我们使用case when 把日期写死了,这个是建立在我们知道是哪天的基础上的。实际中可能是一个变量,但一定也是一个固定的值,需要具体情况具体分析

作者:码农小光
链接:https://www.jianshu.com/p/918f8cea43fc
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值