前两天的那篇内容《MySQL递归实现单列分列成多行》,在公众号没什么反响,但是在百度收到了很好的效果,目前400多的读者中,收藏用户100个,收藏率是21%,还是很高的了;而且阅读完成率是79%,这就更让人意外了。所以今天想再来一篇看看效果如何。
今天的内容还是一个常见的SQL面试题。问题是这样的,现在只有三个渠道(公众号、抖音、知乎)每天的累计粉丝数据,需要查询每天每个渠道新增用户的数据,数据如下↓
实现的思路是,把每个渠道数据找出来分组,然后按日期进行排序,求出日期前一天的累计粉丝数量,在用当天的数据减去前一天的数据就可以了。看到这里,应该就知道了,使用窗口函数里面的LAG语句就可以了,然后使用channel进行PARTITION BY,日期升序就行了,SQL语句和结果如下↓
SELECT
f.*,
LAG(cum_fans,1) OVER(PARTITION BY channel ORDER BY c_date ASC) AS last_day_cfans
FROM
`channel_fans` AS f
这样我们已经求出了每个渠道每天累计的数量,然后只需要进行相减即可,SQL语句和结果如↓
SELECT
f.*,
LAG(cum_fans,1) OVER(PARTITION BY channel ORDER BY c_date ASC) AS last_day_cfans,
f.cum_fans - LAG(cum_fans,1) OVER(PARTITION BY channel ORDER BY c_date ASC) AS add_fans
FROM
`channel_fans` AS f
仔细看结果,是有点问题的,每个渠道第一天的数据是没有的,因为MySQL里面null是个特殊的值,任何数据和它进行运算返回值都是Null。所以我们还需要再完善一下,有两种方式,可以通过IFNULL进行判断,如果是Null就返回0;第二种方式是在LAG里面加入第三个参数,第三个参数是默认值,我们加个0就可以了,SQL语句个结果如下↓
SELECT
f.*,
LAG(cum_fans,1,0) OVER(PARTITION BY channel ORDER BY c_date ASC) AS last_day_cfans,
f.cum_fans - LAG(cum_fans,1,0) OVER(PARTITION BY channel ORDER BY c_date ASC) AS add_fans
FROM
`channel_fans` AS f
好了,到此已经完美解决了问题,窗口函数是个非常好用的系列函数,在做数据预处理的时候能做出很大贡献,可以参考《MySQL窗口_序号函数》、《MySQL窗口_分布、前后、头尾函数》、《MySQL窗口函数_聚合函数》这三篇。
好了,如果能看到最后,又是一个PowerBI使用者的话,再给一个建议。如果是使用数据库,数据需要做预处理,在数据库里面做预处理不仅效率更高,而且可以让PowerBI节约更多的空间,所有PowerBI使用者数据库还是需要掌握的。
End
◆ PowerBI_RFM客户关系模型
◆ PowerBI饼图、圈图、旭日图
◆ Excel时间序列预测函数
◆ Python操作MySQL数据库
◆ Python企业微信机器人