100个SQL小知识

@ 100个SQL小知识

千里之行,始于足下

1. distance 从 0 米到10000米, 20米一档分为 500档

floor(distance/200)*200 as distance

2. grouping sets

select business_mode, source, count(uid)
from order_base
group by business_mode, source
grouping sets(business_mode);
达到group by 全部纬度一次, business_mode一次 union这两个表
详情见

3. [面筋] 查询6月1日到30日的观看时长0-60s,1-3min,3-10min…5个组的观看人数

select count(distinct if(duration <= 60, uid, null)) as '0~60s'
from (select uid, sum(duration) as duration
		from t1
		where date between '2020-06-01' and '2020-06-30'
		group by uid) tt1

进阶版—

用窗口函数代替子查询?

4. [面筋]查询每个组grp排序第2的uid

窗口函数 dense_rank

dense_rank, 出现并列第一, 第二名依然会返回2; rank并列第一, 第二名会返回3.

5. 次周留存的解法

周日苦哈哈加班写留存报表固化的我, 灵机一动, 想到了一个次周留存的新解法~

留存新算法整理

好处:一个SQL计算, 新老周留存+本周频次

select shop_id, new_user_week_mark
	, count( distinct if(if_come_last_week = 0, uid, null)) as last_week_user_cnt -- 上周有多少客人
	, count(distinct if(come_both_week = 2, uid, null)) as last_week_user_re -- 上周客人这周留存
	, sum(order_cnt) as order_cnt --- 本周单量/用于计算周频次
	, count(distinct if (come_both_week = 2 or if_last_week = 0 , uid, null)) as this_week_user_cnt
	--- 本周用户数 = 这周的新课客(上周没来,这周来了 if_come_last_week = 1 ) + 上周的回头客 (come_both_week = 1) 

from (select shop_id, uid
		, min(week_num)  as if_come_last_week
		 -- 可以用来算上周客人的基数: 一个用户最小的week_num为0代表他上周有来; 为1代表上周没来
		, count(distinct week_num) as come_both_week  
		-- 是否两周都来了(即为上周客人这周留存):一个用户具有两个week_num
		, count(distinct if(week_num = 1, order_id, null)as order_cnt --- 计算本周频次用 
fromselect shop_id, uid , order_id
,if(complete_time between '2021-03-01' and '2021-03-07', 0, 1) as week_num --- 0是上周, 1是本周
from order) tt0
group by shop_id, uid ) t0
		left join (
select uid, case when first_complete_time between '2021-03-01' and '2021-03-07' then ' last' 
			 when first_complete_time between '2021-03-08' and '2021-03-14' then 'this' 
			else 'else' end as new_user_week_mark
from user_info 
			) t1
group by shop_id, new_user_week_mark
6. grouping sets

同时得到a ,b ,c 维度下去重的uid_cnt,和 a,b维度下的uid_cnt

select  a, b,c, count(distinct uid) as uid_cnt
from t0
where concat_ws('-',year,month,day) between '2021-03-29' and '2021-03-30'
group by a, b,c
grouping sets ( (a, b), (a, b,c)) -- 指示按照这两种维度分别聚合一次

7. grouping sets

找到各种维度聚合的grouping——id

select stat_date, count(*)
,case when GROUPING__ID = 2 then 'total'
            when GROUPING__ID = 1 and category_name is null then 'other' else category_name end as category_name
            ,GROUPING__ID as grouping_id
from t1
group by ( (stat_date, category_name), stat_date)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值