MySQL 按月获取累计客户交易(不是 SQL 交易)
MySQL Get cumulative customer transactions (not SQL transactions) on a monthly basis
:)
我有一个简单的 table,里面有交易,没什么特别的,我想知道每个月有多少笔交易 "first transactions"。第一次交易是指客户当时第一次购买。
我试图得到的结果是以下形式:
+---------+----------------------------+------------------+
| Date | First Purchases In Month | Cumulative Sum |
+---------+----------------------------+------------------+
| 01/2015 | 10 | 10 |
+---------+----------------------------+------------------+
| 02/2015 | 40 | 50 |
+---------+----------------------------+------------------+
日期格式无所谓,可以是完整日期,反正我稍后会在Java解析。
我发现这个 post 每天都会做类似的事情
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
结果似乎是正确的,但使用如此多的内部查询似乎并不是最佳实践方法。做这样的事情的建议方法是什么?
此外,当一个月中没有 "first transactions" 而不是那个日期根本不出现时,我想得到 0(比如我们的 fiddle 中只有一个交易的三月不是 "first transaction").
非常感谢您的提前帮助! :)
最简单的方法是按客户汇总以获得每个客户的第一笔交易日期。然后总结一下:
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;
处理首次交易为零的月份也很痛苦。如果您有日历 table 或知道当月有一些交易,这会有所帮助。例如,您可以这样做:
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;
:)
我有一个简单的 table,里面有交易,没什么特别的,我想知道每个月有多少笔交易 "first transactions"。第一次交易是指客户当时第一次购买。
我试图得到的结果是以下形式:
+---------+----------------------------+------------------+
| Date | First Purchases In Month | Cumulative Sum |
+---------+----------------------------+------------------+
| 01/2015 | 10 | 10 |
+---------+----------------------------+------------------+
| 02/2015 | 40 | 50 |
+---------+----------------------------+------------------+
日期格式无所谓,可以是完整日期,反正我稍后会在Java解析。
我发现这个 post 每天都会做类似的事情
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
结果似乎是正确的,但使用如此多的内部查询似乎并不是最佳实践方法。做这样的事情的建议方法是什么?
此外,当一个月中没有 "first transactions" 而不是那个日期根本不出现时,我想得到 0(比如我们的 fiddle 中只有一个交易的三月不是 "first transaction").
非常感谢您的提前帮助! :)
最简单的方法是按客户汇总以获得每个客户的第一笔交易日期。然后总结一下:
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;
处理首次交易为零的月份也很痛苦。如果您有日历 table 或知道当月有一些交易,这会有所帮助。例如,您可以这样做:
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;