我有一个mySQL数据库,每行包含一个激活和停用日期。这指的是行所代表的对象处于活动状态的时间段。
activate deactivate id
2015-03-01 2015-05-10 1
2013-02-04 2014-08-23 2
我想在每个月的任何时间找到活动的行数。实施例
Jan: 4
Feb: 2
Mar: 1
etc...
我想出了如何在一个月内完成这项工作,但是我在单一查询中一年内所有12个月都在努力解决这个问题。我想在单个查询中使用它的原因是性能,因为信息是立即使用的,而缓存在这种情况下没有意义。这是我一次有一个月的代码。它会检查激活日期是否在相关月份的月末之前,并且停用日期不在相关期间的开始之前。
SELECT * from tblName WHERE activate <= DATE_SUB(NOW(), INTERVAL 1 MONTH)
AND deactivate >= DATE_SUB(NOW(), INTERVAL 2 MONTH)
如果有人知道如何改变这一点并进行分组,我可以无限期地进行分组,我会很感激。我不知道如何分组。
答案 0 :(得分:2)
如果你有一个你关心的月份表,你可以这样做:
select m.*,
(select count(*)
from table t
where t.activate_date <= m.month_end and
t.deactivate_date >= m.month_start
) as Actives
from months m;
如果您没有这样的桌子,您可以动态创建一个:
select m.*,
(select count(*)
from table t
where t.activate_date <= m.month_end and
t.deactivate_date >= m.month_start
) as Actives
from (select date('2015-01-01') as month_start, date('2015-01-31') as month_end union all
select date('2015-02-01') as month_start, date('2015-02-28') as month_end union all
select date('2015-03-01') as month_start, date('2015-03-31') as month_end union all
select date('2015-04-01') as month_start, date('2015-04-30') as month_end
) m;
编辑:
一种可能更快的方法是计算激活和停用的累积总和,然后采用每月的最大值:
select year(date), month(date), max(cumes)
from (select d, (@s := @s + inc) as cumes
from (select activate_date as d, 1 as inc from table t union all
select deactivate_date, -1 as inc from table t
) t cross join
(select @s := 0) param
order by d
) s
group by year(date), month(date);