基于购买日期的每日消费增量

mcdcgff0  于 2021-06-18  发布在  Mysql
关注(0)|答案(1)|浏览(316)

我需要做一个(表)每日图表描绘消费动态与前一天分组的客户谁增加消费,减少消费,净变化总体。样本如下。
示例的计算逻辑:对于每个客户的每一天,计算该客户与前一天的差异,将高于0的求和,低于0的求和,合计。

样本是从一个相对较小的数据集中手工制作的。真正的表有超过200万行,而且不太一致,因为客户在不同的日期开始购买,可能会跳过不同的时段,什么也不买。初始表结构如下:

client_id   date    sales
    1   2018-09-01  4
    1   2018-09-02  5
    1   2018-09-04  3
    2   2018-09-1   2
    2   2018-09-2   2

虽然计算每个日期的表差异很简单,但是计算纯增长和纯流失很困难,因为日期行不是所有客户机都连续的。在从数据存储加载初始数据集时,我考虑将delta\u to\u previous列添加到每一行,如:

WITH orders AS (
    SELECT client_id,
           date,
           SUM(sales) as sales
    FROM dwh_orders
    GROUP BY client_id, date
)
SELECT
    client_id, 
    date, 
    sales,
    LAG(sales, 1) OVER (
        PARTITION BY client_id
        ORDER BY date
    ) as prev_date_order_value,
    sales - LAG(sales, 1) OVER (
        PARTITION BY client_id
        ORDER BY date
    ) as prev_date_order_delta
FROM 
    orders;

然后,对于每个日期,我可以只显示正值、负值和总和。
问题是,这种方法会在下一个购买日期显示消费变化,如果客户在3月1日购买了5件商品,然后在5月1日购买了5件商品,那么对他来说根本没有变化。它应该做的是3月2日显示-5,5月1日显示+5。
我对解决这个问题的最佳方法有点困惑。一般的解决方案也可能需要一些审查。
如果有人处理类似的问题,我真的需要你的建议。如果您有sql方面的经验,我可以使用您关于如何将初始数据集(参见上面的示例)转换为

client_id   date    sales delta
    1   2018-09-01  4   0
    1   2018-09-02  5   1
    1   2018-09-03  0   -5
    1   2018-09-04  3   3
    2   2018-09-1   2   0
    2   2018-09-2   2   0

如果你对tableau有点了解的话,我可以使用它的工具来帮助你构建这样的图。

fhity93d

fhity93d1#

with cdates as (
      select client_id, min(date) as dte, max(date) as maxd
      from dwh_orders
      group by client_id
      union all
      select client_id, dateadd(day, 1, dte), maxd
      from cdates
      where dte < maxd
     ),
     cd as (
      select client_id, date, sum(sales) as sales
      from dwh_orders
      group by client_id, date
    )
select cdates.client_id, cdates.date,
       coalesce(sales, 0) as sales,
       (coalesce(sales, 0) -
        lag(coalesce(sales, 0)) over (partition by cdates.client_id order by cdates.date
       ) as delta
from cdates left join
     cd
     on cdates.client_id = cd.client_id and
        cdates.date = cd.date
option (maxrecursion 0);

相关问题