【问题标题】:Find number of "active" rows each month for multiple months in one query在一个查询中查找多个月的每个月的“活动”行数
【发布时间】:2015-07-22 18:14:20
【问题描述】:

我有一个 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) 

如果有人知道如何更改此设置并进行分组,以便我可以无限期地执行此操作,我将不胜感激。我不知道如何分组。

【问题讨论】:

  • 在您的样本中,Id=1 是否在第 3,4 个月和第 5 个月处于活动状态?所以会在所有三个月内添加吗?相同的 Id=2 将添加 (2,3,4,5,6,7,8)
  • @JuanCarlosOropeza 是的,我想知道每个月有多少行处于活动状态,因此多个月处于活动状态的项目将计入每个月的计数。
  • 我想 Gordon 已经给你答案了。如果您需要其他任何内容,请添加其他评论。

标签: mysql sql


【解决方案1】:

如果你有一个你关心的月份表,你可以这样做:

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);

【讨论】:

  • 它可以工作,但在我们的生产服务器上运行需要 12 秒。我将尝试找到一种更快的方法。
猜你喜欢
  • 2013-03-12
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多