抽奖逻辑说明
在某个时段内,会员在超市内下单,就有机会得到超市派送的惊喜小礼物
业务说明和价值说明
- 在门店经营过程中,经常在一些节假日里面做一些抽奖活动,为门店带来线上或者线下的客流。
- 客流的增加很容易带动销售额的上涨。
- 抽奖也是的超市常用的促销手段。
超市的主要商业场景
随着智能手机的普及,超市越来越意识到 APP 在触达用户方面的优势,所以纷纷推出了自己的微信小程序或者独立的 APP。利用这种手动,超市可以更加快捷、高效的做一些线上的活动,例如,有著名的双 11、双 12 等等。其中抽奖就是一个重要玩法。这种玩法更加的公平,减少了人为的干预。另外,这种线上的运营手法,可以增加超市的存在感,增加用户的粘性。
商业知识点思考
这个涉及到了线上和线下运营的知识,早前互联网没有这样普及的时候,商家为了吸引客流,要兴师动众的请歌手、二人转到商城表演,这是利用了名人效应。也可以在黄金时段,电视上插播广告,这是利用了广播电视的手段。来到了移动互联网的时代,商家可以通过手机这种高效的手段触达用户,吸引客流。
SQL 知识点
- random() 随机函数
- count、row_number 分析函数
逻辑说明
- 找出在某个时间区间里面有消费记录的会员编号
- 为会员编号随机的排序
- 为排好序的会员列表添加序号
- 取出序号小于总会员数的 30%
/*
dimMemberID:会员 ID
dimDateID:下单日期
dimShopID:门店 ID
取出门店、会员的 ID 号,并使用 group by 进行去重操作
*/
select dimShopID , dimMemberID
from dw.fct_sales
where dimDateID between 20170602 and 20170602
group by dimShopID ,dimMemberID
select dimShopID
, dimMemberID
, row_number() over(partition by dimShopID order by random() ) as rn
, count(dimMemberID) over(partition by dimShopID ) as member_cnt
from (
select dimShopID , dimMemberID
from dw.fct_sales
where dimDateID between 20170602 and 20170602
group by dimShopID ,dimMemberID
) as q1
上面这段有点复杂了,让我一一道来。
row_number 的功能是给表里每一个记录加一个序号,举个例子
会员 ID | row_number |
A | 1 |
B | 2 |
C | 3 |
D | 4 |
如上面的表格所示,第一列是会员的 ID,第二列是 row_number 生成的序号,就像我们到店里面吃麻辣烫,我挑完菜品以后,收银员会给我们一个号牌,这个号牌有个特点,就是不能重号,因为如果当店员喊 23 号来取餐,来了两个人拿着同样的号牌来取餐,这将成为一个事故现场。我们相当于每个会员一个号牌,我们根据号牌来找到幸运顾客,例如,我们可以直接说号码小于 30 的顾客是幸运儿。那么我们怎么做到每个顾客拿到的前三十个号牌的概率是相同的呢?
random() 函数帮我们解决了这个问题,那么 random 是何许人也呢?请看下面的例子:
会员 ID | random |
A | 0.1 |
B | 0.2 |
C | 0.3 |
D | 0.4 |
当扫描到表中其中一行记录的时候,random 会随机的生成一个小于 1 的小数,由于每个记录生成的小数是随机的,那么 A、B、C、D 拿到 0.1 的概率也是相同。这就达到公平了。
啰嗦了这么多,还是讲 row_number + random 的用法吧
row_number() over(partition by dimShopID order by random() )
,其中 partition by dimShopID 是限定不同的店下面要从 1 开始生成序号,例如:
店编 | 会员 ID | row_number |
店1 | A | 1 |
店1 | B | 2 |
店2 | C | 1 |
店2 | D | 2 |
从上面的例子可以看到,当从店1变到店2的时候,row_number 会从 1 开始排号。
然后 order by random() 会根据随机生成的小数排序。
count(dimMemberID) over(partition by dimShopID ) as member_cnt
这一句的意思是统计不同门店里面有多少个会员
通过以后步骤,我们会得到每家门店的会员数、随机排序的会员列表,接着我们可以计算
出每家门店的 30% 的会员数量(设为 a),然后我们再序号把小于 a 的会员过滤出来,大功告成了。最后的结果如下所示:
select dimShopID
from (
select dimShopID
, dimMemberID
, row_number() over(partition by dimShopID order by random() ) as rn
, count(dimMemberID) over(partition by dimShopID ) as member_cnt
from (
select dimShopID , dimMemberID
from dw.fct_sales
where dimDateID between 20170602 and 20170602
group by dimShopID ,dimMemberID
) as q1
) as q2
where rn <= member_cnt*0.3