:)
我有一个简单的表,里面有交易,没什么特别的,我想每个月得到多少交易是“第一笔交易”。第一笔交易是指客户第一次购买。
我想要获得的结果如下:
+---------+----------------------------+------------------+
| 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(就像我们小提琴中的三月只有一笔不是“第一笔交易”的交易一样) )。
非常感谢您提前提供的任何帮助! :)
答案 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;