两表左连接count某一字段_表连接解决多日留存率问题|SQL
一、留存率的計算
留存率=新增用戶中登錄用戶數/新增用戶數*100%
第N日留存:指的是新增用戶日之后的第N日依然登錄的用戶數/新增用戶數*100%
二、數據集的理解
表【登錄情況】中有字段【用戶id】,【登陸日期】,用戶id和登陸日期能夠標識一行數據。
登陸情況表的部分數據三、計算多日留存率
(1)將日期、用戶id做關聯,進行多個連接。
注意:
1、新增用戶的定義:某日的新增用戶是指在這一天之前沒有登陸信息的用戶。
每一天產生的新增用戶名單作表a,思路如下:
將登陸情況和登陸情況連接——表s1和s2
以用戶id和日期做關聯條件——s2 on s1.用戶id=s2.用戶id and s1.日期>s2.日期
再加上查詢條件——s2.日期 is null
2、只計算次日留存率需要連接2個表,計算次日、二日、三日、四日留存率需要連接四個表。
計算次日留存率思路如下:
將a表和登陸情況連接——表a和表b
以用戶id和日期作關聯條件——a.用戶id=b.用戶id and b.日期=date_add(a.日期,interval 1 day)
再將b表中的留存用戶數取出 ——count(distinct b.用戶id)
計算留存率——concat、round
上面自連接的方法固然可行但多次關聯在執行效率上會有瓶頸。更好的方法如下:
(2)將用戶id做關聯,進行一個連接,直接在最外層查詢時根據自己的目標限定日期差。
注意:
1、a表和上面的相同
2、只連接a表和登陸情況表,只以用戶id為關聯條件
3、外層查詢用到 if 和 datediff 來限定日期差,如果滿足條件,則返回b表的用戶id。
select a.日期, count(distinct a.用戶id) as 日新增用戶數, concat(round(100*count(distinct if(datediff(b.日期,a.日期)=1, b.用戶id, null))/count(distinct a.用戶id),2),'%') as 次日留存率, concat(round(100*count(distinct if(datediff(b.日期,a.日期)=2, b.用戶id, null))/count(distinct a.用戶id),2),'%') as 二日留存率, concat(round(100*count(distinct if(datediff(b.日期,a.日期)=3, b.用戶id, null))/count(distinct a.用戶id),2),'%') as 三日留存率, concat(round(100*count(distinct if(datediff(b.日期,a.日期)=4, b.用戶id, null))/count(distinct a.用戶id),2),'%') as 四日留存率, concat(round(100*count(distinct if(datediff(b.日期,a.日期)=5, b.用戶id, null))/count(distinct a.用戶id),2),'%') as 五日留存率, concat(round(100*count(distinct if(datediff(b.日期,a.日期)=6, b.用戶id, null))/count(distinct a.用戶id),2),'%') as 六日留存率, concat(round(100*count(distinct if(datediff(b.日期,a.日期)=7, b.用戶id, null))/count(distinct a.用戶id),2),'%') as 七日留存率, concat(round(100*count(distinct if(datediff(b.日期,a.日期)=8, b.用戶id, null))/count(distinct a.用戶id),2),'%') as 八日留存率 from (select s1.*from 登陸情況 as s1 left join 登陸情況 as s2 on s1.用戶id=s2.用戶id and s1.日期>s2.日期where s2.日期 is null) as a #每日新增的用戶名單 left join 登陸情況 as b on a.用戶id=b.用戶id group by a.日期總結
以上是生活随笔為你收集整理的两表左连接count某一字段_表连接解决多日留存率问题|SQL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: fastjson jar包_经过性能对比
- 下一篇: python123作业怎么提交_pyth