zoukankan      html  css  js  c++  java
  • MySQL-计算当月重新激活客户_20161013

      13号的草稿 12号的明天补充更新,最近太忙了。

      客户留存率是衡量客户价值经常用的指标,可以反映客户的活跃程度,在互联网企业,尤其是现在手机端流量已经超过PC端流量,在安卓和IOS设备上在线时长的数据,电商APP产品的下单频次都可以反映客户的活跃情况。

      近期公司销售人员也需要一些数据,考察销售人员在当月的新开发客户和重新激活客户。

      这里我们定义规则是当月下单过的客户为活跃客户,激活客户为在本月下单,上次下单距离本月下单时间超过30天(今天改了2次代码和客户运营同事沟通知道他们以这个间隔来进行定义客户新增激活留存属性,之前为了配合月报都是以整月为单位,因此出数据之前沟通是很有必要的,统计口径不一样,得到的结果就是互相桑害(⊙o⊙)) 

      我是这么考虑的。

      考虑到数据库数据更新截止到昨天为止,月初每个月1号时候数据实际是上个月的完整数据,新的一月实际是没数据的,因此1号出数据依然是计算上个月的,2号就是计算新的一月的,因此当月指的是除了每月1号是指上月,其他都是当前月 

      #DATE_FORMAT(DATE_ADD(CURRENT_DATE,INTERVAL -1 DAY) 就是解决每个月1号出现1月所在月数据为空的问题

      1、如果要在表中生成一个留存属性的字段需要判断客户在当月是新增客户,还是留存客户还是重激活客户,需要先把当月客户每天的明细先调出来,找到用户在当月下单的第一天的日期,以这个日期往前推30天判断)下面是代码

    SELECT a2.用户ID,a2.订单日期 AS 当月首单日,a2.销售员,a2.订单额 AS 当月首单额#取当月首单日,当月首单销售员,当月首单额
    FROM (
        SELECT a1.username AS 用户ID,a1.order_date AS 订单日期,a1.salesperson AS 销售员,SUM(a1.pay_money) AS 订单额#当月每一天明细
        FROM test_a03order AS a1
        WHERE a1.city="city_A" AND DATE_FORMAT(a1.order_date,"%Y%m")=DATE_FORMAT(DATE_ADD(CURRENT_DATE,INTERVAL -1 DAY),"%Y%m")
        GROUP BY a1.username,a1.order_date
    ) AS a2
    GROUP BY a2.用户ID

    2、上面代码把当月下单的客户名单找出来了 用户不重复,一行一个记录 我们以上面代码生成的字段 当月首单日 为基准 再用left join 订单表 去判断用户属性

    SELECT a3.用户ID,a3.当月首单日,a3.销售员,
    SUM(IF(a4.order_date<DATE_ADD(a3.当月首单日,INTERVAL -30 DAY),pay_money,NULL)) AS 当月首单日前30天之前订单额,
    SUM(IF(a4.order_date>=DATE_ADD(a3.当月首单日,INTERVAL -30 DAY) AND a4.order_date<a3.当月首单日,pay_money,NULL)) AS 当月首单日前30天订单额,
    SUM(IF(a4.order_date<a3.当月首单日,pay_money,NULL)) AS 当月首单日之前总订单额,
    a3.当月首单额,
    CASE 
    WHEN SUM(IF(a4.order_date<a3.当月首单日,pay_money,NULL)) IS NULL THEN "新增"#x1 
    WHEN SUM(IF(a4.order_date>=DATE_ADD(a3.当月首单日,INTERVAL -30 DAY) AND a4.order_date<a3.当月首单日,pay_money,NULL))IS NOT NULL THEN "留存"#x2
    WHEN SUM(IF(a4.order_date<DATE_ADD(a3.当月首单日,INTERVAL -30 DAY),pay_money,NULL)) IS NOT NULL AND SUM(IF(a4.order_date>=DATE_ADD(a3.当月首单日,INTERVAL -30 DAY) AND a4.order_date<a3.当月首单日,pay_money,NULL))IS  NULL THEN "重激活"#x3
    ELSE NULL END 留存情况
    FROM (
        SELECT a2.用户ID,a2.订单日期 AS 当月首单日,a2.销售员,a2.订单额 AS 当月首单额#取当月首单日,当月首单销售员,当月首单额
        FROM (
            SELECT a1.username AS 用户ID,a1.order_date AS 订单日期,a1.salesperson AS 销售员,SUM(a1.pay_money) AS 订单额#当月每一天明细
            FROM test_a03order AS a1
            WHERE a1.city="city_A" AND DATE_FORMAT(a1.order_date,"%Y%m")=DATE_FORMAT(DATE_ADD(CURRENT_DATE,INTERVAL -1 DAY),"%Y%m")
            GROUP BY a1.username,a1.order_date
        ) AS a2
        GROUP BY a2.用户ID
    ) AS a3
    LEFT JOIN test_a03order AS a4 ON a3.用户ID=a4.username#a3是在当月下单的用户 再去找这些用户在整个订单表的订单情况 以a3的当月首单日往前推算30天计算留存新增等属性
    GROUP BY a3.用户ID

    #x1 说明在当月首单日之前没下过单 这是新客户

    #x2说明在当月首单日之前30天下过单 当月首单日距上次最后一次下单间隔不超过30天 这是留存客户

    #x3说明在首单日前30天再之前下过单 在距离当月首单日30天内没下过单 重激活

    实质上是数学上区间判断的问题 区间点包含不包含和运营人沟通一下就解决

    区间节点分别为60之前,60,90

    <=60 这段为a区间

    (60,90)为b区间

    =90 为c区间

    <90为d 区间 代表a和b的全部区间

    因此转化到区间判断上了 首先c区间肯定有金额 代表本月首单日金额

    新增:d区间金额为空,c不为空 因此新下单

    留存:b区间金额不为空 则留存

    重激活:a区间金额不为空,b区间为空,c区间不为空 则重激活

  • 相关阅读:
    Luogu P4002 [清华集训2017]生成树计数
    Luogu P3978 [TJOI2015]概率论
    Codechef JADUGAR2 Chef and Same Old Recurrence 2
    Codechef TREDEG Trees and Degrees
    一些有趣的数
    有向图上Euler回路计数
    P5105 不强制在线的动态快速排序
    二分图小结
    BZOJ2648: SJY摆棋子
    P3231 [HNOI2013]消毒
  • 原文地址:https://www.cnblogs.com/Mr-Cxy/p/5958869.html
Copyright © 2011-2022 走看看