使用 mysql 获取过去 12 个月的数据
Getting data from the last 12 month using mysql
我的 table 中有以下数据结构:
id member_from member_till
1 2014/03/01 2014/05/18
2 2014/01/09 2014/08/13
...
我如何获得过去 12 个月的活跃成员数,按月分组?
例如:
...
2014/12/01,5
2015/01/01,12
作为未来的发展,是否可以将每个月的第一天和最后一天的计数取平均值?
首先你需要过去十二个月的时间。然后外联成员,统计月份在成员范围内的成员。
select
date_format(all_months.someday, '%Y %m') as mymonth,
count(membership.member_from) as members
from
(
select current_date as someday
union all
select date_add(current_date, interval -1 month)
union all
select date_add(current_date, interval -2 month)
union all
select date_add(current_date, interval -3 month)
union all
select date_add(current_date, interval -4 month)
union all
select date_add(current_date, interval -5 month)
union all
select date_add(current_date, interval -6 month)
union all
select date_add(current_date, interval -7 month)
union all
select date_add(current_date, interval -8 month)
union all
select date_add(current_date, interval -9 month)
union all
select date_add(current_date, interval -10 month)
union all
select date_add(current_date, interval -11 month)
) all_months
left join membership
on date_format(all_months.someday, '%Y %m')
between
date_format(membership.member_from, '%Y %m')
and
date_format(membership.member_till, '%Y %m')
group by date_format(all_months.someday, '%Y %m');
SQL fiddle: http://www.sqlfiddle.com/#!2/6dc5a/10.
关于您以后的要求:您可以加入会员table两次,一次是在一个月的第一天,一次是在这个月的最后一天(失去那些只参加了几天的会员)月中旬)。然后将两个计数相加并除以二。
您可以尝试使用 SQL 查询:
SELECT `member_from`, count(id) FROM tbl_test WHERE `member_from` BETWEEN <From date> AND <To date> GROUP BY `member_from`;
完成未来要求:
SELECT
d.ymonth,
COUNT(m.member_from) total,
COALESCE(SUM(d.fday BETWEEN m.member_from AND m.member_till), 0) total_fom,
COALESCE(SUM(d.lday BETWEEN m.member_from AND m.member_till), 0) total_lom
FROM
(
SELECT
CAST(@first_day := @first_day + INTERVAL 1 MONTH AS DATE) fday,
LAST_DAY(@first_day) lday,
DATE_FORMAT(@first_day, '%Y-%m') ymonth
FROM
information_schema.collations
CROSS JOIN
(SELECT @first_day := LAST_DAY(CURRENT_DATE) - INTERVAL 13 MONTH + INTERVAL 1 DAY) x
LIMIT 12
) d
LEFT JOIN
membership m
ON d.lday >= m.member_from
AND d.fday <= m.member_till
GROUP BY d.ymonth
子查询生成一个包含 3 列的虚拟查找 table:
+ ---------- + ---------- + ------- +
| fday | lday | ymonth |
+ ---------- + ---------- + ------- +
| 2014-02-01 | 2014-02-28 | 2014-02 |
| \/ | \/ | \/ |
| 2015-01-01 | 2015-01-31 | 2015-01 |
+ ---------- + ---------- + ------- +
然后可以在重叠 member_from-member_till 以及每个月的开始和结束时加入会员 table。
我的 table 中有以下数据结构:
id member_from member_till
1 2014/03/01 2014/05/18
2 2014/01/09 2014/08/13
...
我如何获得过去 12 个月的活跃成员数,按月分组?
例如:
...
2014/12/01,5
2015/01/01,12
作为未来的发展,是否可以将每个月的第一天和最后一天的计数取平均值?
首先你需要过去十二个月的时间。然后外联成员,统计月份在成员范围内的成员。
select
date_format(all_months.someday, '%Y %m') as mymonth,
count(membership.member_from) as members
from
(
select current_date as someday
union all
select date_add(current_date, interval -1 month)
union all
select date_add(current_date, interval -2 month)
union all
select date_add(current_date, interval -3 month)
union all
select date_add(current_date, interval -4 month)
union all
select date_add(current_date, interval -5 month)
union all
select date_add(current_date, interval -6 month)
union all
select date_add(current_date, interval -7 month)
union all
select date_add(current_date, interval -8 month)
union all
select date_add(current_date, interval -9 month)
union all
select date_add(current_date, interval -10 month)
union all
select date_add(current_date, interval -11 month)
) all_months
left join membership
on date_format(all_months.someday, '%Y %m')
between
date_format(membership.member_from, '%Y %m')
and
date_format(membership.member_till, '%Y %m')
group by date_format(all_months.someday, '%Y %m');
SQL fiddle: http://www.sqlfiddle.com/#!2/6dc5a/10.
关于您以后的要求:您可以加入会员table两次,一次是在一个月的第一天,一次是在这个月的最后一天(失去那些只参加了几天的会员)月中旬)。然后将两个计数相加并除以二。
您可以尝试使用 SQL 查询:
SELECT `member_from`, count(id) FROM tbl_test WHERE `member_from` BETWEEN <From date> AND <To date> GROUP BY `member_from`;
完成未来要求:
SELECT
d.ymonth,
COUNT(m.member_from) total,
COALESCE(SUM(d.fday BETWEEN m.member_from AND m.member_till), 0) total_fom,
COALESCE(SUM(d.lday BETWEEN m.member_from AND m.member_till), 0) total_lom
FROM
(
SELECT
CAST(@first_day := @first_day + INTERVAL 1 MONTH AS DATE) fday,
LAST_DAY(@first_day) lday,
DATE_FORMAT(@first_day, '%Y-%m') ymonth
FROM
information_schema.collations
CROSS JOIN
(SELECT @first_day := LAST_DAY(CURRENT_DATE) - INTERVAL 13 MONTH + INTERVAL 1 DAY) x
LIMIT 12
) d
LEFT JOIN
membership m
ON d.lday >= m.member_from
AND d.fday <= m.member_till
GROUP BY d.ymonth
子查询生成一个包含 3 列的虚拟查找 table:
+ ---------- + ---------- + ------- +
| fday | lday | ymonth |
+ ---------- + ---------- + ------- +
| 2014-02-01 | 2014-02-28 | 2014-02 |
| \/ | \/ | \/ |
| 2015-01-01 | 2015-01-31 | 2015-01 |
+ ---------- + ---------- + ------- +
然后可以在重叠 member_from-member_till 以及每个月的开始和结束时加入会员 table。