MySQL每月获取累积客户交易(不是SQL交易)

时间:2015-07-24 14:43:23

标签: mysql sql subquery

:)

我有一个简单的表,里面有交易,没什么特别的,我想每个月得到多少交易是“第一笔交易”。第一笔交易是指客户第一次购买。

我想要获得的结果如下:

+---------+----------------------------+------------------+
|   Date  |  First Purchases In Month  |  Cumulative Sum  |
+---------+----------------------------+------------------+
| 01/2015 |           10               |       10         |
+---------+----------------------------+------------------+
| 02/2015 |           40               |       50         |
+---------+----------------------------+------------------+

日期格式并不重要,它可能是一个完整的日期,我将在以后用Java解析它。

我发现这篇帖子虽然每天都做类似的事情

How can i get count of customers per day by unique and repeat customer for specific date?

我把它变成了这个:

set @csum := 0;
SELECT
    FirstOrderDate, MonthTotal, @csum:= @csum + MonthTotal AS AccumulatedTotal
FROM
(
    SELECT FirstOrderDate, SUM(month_total_new) as MonthTotal
    FROM
    (
        SELECT
            FirstOrderDate, COUNT(q1.consumerId) AS month_total_new
        FROM
        (
            SELECT
                consumerId, MIN(date) AS FirstOrderDate
            FROM
                transaction
            GROUP BY
                consumerId
        ) AS q1
        GROUP BY
            EXTRACT(YEAR FROM q1.FirstOrderDate),
            EXTRACT(MONTH FROM q1.FirstOrderDate)
    ) AS s
    GROUP BY
        EXTRACT(YEAR FROM s.FirstOrderDate),
        EXTRACT(MONTH FROM s.FirstOrderDate)
) AS test;

您可以在此处看到它:http://sqlfiddle.com/#!9/31538/7

结果似乎是正确的,但使用如此多的内部查询似乎并不是最佳实践方法。提出这样做​​的方法是什么?

另外,我想在一个月内没有“第一笔交易”而不是那个根本没有出现的日期时得到0(就像我们小提琴中的三月只有一笔不是“第一笔交易”的交易一样) )。

非常感谢您提前提供的任何帮助! :)

1 个答案:

答案 0 :(得分:0)

最简单的方法是按客户汇总以获取每位客户的第一笔交易日期。然后总结一下:

  select year(firstdate) as yyyy, month(firstdate) as mm,
         count(*) as NumFirsts
  from (select consumerid, min(date) as firstdate
        from transaction
        group by consumerid
       ) c
  group by year(firstdate), month(firstdate)
  order by year(firstdate), month(firstdate);

如果您在java中阅读此内容,您可能只想在那里进行累积求和。否则,您可以使用变量在MySQL中执行此操作:

select c.*, (@s := @s + NumFirsts) as CumeFirsts
from (select year(firstdate) as yyyy, month(firstdate) as mm,
             count(*) as NumFirsts
      from (select consumerid, min(date) as firstdate
            from transaction
            group by consumerid
           ) c
      group by year(firstdate), month(firstdate)
     ) c cross join
     (select @s := 0) params
order by yyyy, mm;

处理零首次交易的月份也很痛苦。如果你有一个日历表或者知道这个月有一些交易,它会有所帮助。例如,你可以这样做:

select ym.yyyy, ym.mm, coalesce(NumFirsts, 0) as NumFirsts,
       (@s := @s + coalesce(NumFirsts, 0)) as CumeFirsts
from (select distinct year(date) as yyyy, month(date)
      from transactions
     ) ym left join
     (select year(firstdate) as yyyy, month(firstdate) as mm,
             count(*) as NumFirsts
      from (select consumerid, min(date) as firstdate
            from transaction
            group by consumerid
           ) c
      group by year(firstdate), month(firstdate)
     ) c
     on c.yyyy = ym.yyyy and c.mm = y.mm cross join
     (select @s := 0) params
order by yyyy, mm;