Mysql 按月计算的活动成员数。。。

Mysql 按月计算的活动成员数。。。,mysql,Mysql,正在寻找解决此问题的优雅解决方案。。。我发现我做的任何事都很丑陋。。。我只想画出每个月有多少活跃用户(在开始/结束日期内)。当然,我需要一个0的计数,其中该月在该报告日期范围内没有活动用户 TABLE MEMBERSHIPS Name, Start_date, End_date Joe, 2017/02/01, 2017/04/01 Bob, 2017/03/01, 2017/05/01 Moe, 2017/03/01, 2017/05/01 Lou, 2017/04/01, 2017/

正在寻找解决此问题的优雅解决方案。。。我发现我做的任何事都很丑陋。。。我只想画出每个月有多少活跃用户(在开始/结束日期内)。当然,我需要一个0的计数,其中该月在该报告日期范围内没有活动用户

TABLE MEMBERSHIPS
Name, Start_date, End_date
Joe,  2017/02/01, 2017/04/01
Bob,  2017/03/01, 2017/05/01
Moe,  2017/03/01, 2017/05/01
Lou,  2017/04/01, 2017/05/01
所以我需要一份每月活跃会员的报告。。。也就是说,在给定的范围内,在给定的月份有多少成员处于活动状态的计数。。。因此,预期结果:

Reoort for 2017/01/01 to 2017/06/01

Month, Count
 01  |  0
 02  |  1
 03  |  3
 04  |  4
 05  |  3
 06  |  0
我相信这是一个常见的用例。。。只是找不到任何好东西


谢谢,

这里的问题是创建报告所需的部分数据丢失。数据库如何知道您希望包括第01个月,尽管该月没有数据

解决这个问题的一个简单方法是创建一个表,其中包含报告应包含的所有月份。为了进一步简化,只需在该表中写入相应月份的任意日期,而不是年份和月份本身

Table ReportMonths:
ReportMonth datetime
2017-01-15
2017-02-15
2017-03-15
2017-14-15
2017-05-15
2017-06-15
要使用新表创建报告,请执行以下操作:

SELECT
  ReportMonths.ReportMonth,
  COUNT(*)
FROM
  ReportMonths, MEMBERSHIPS
WHERE
  (MEMBERSHIPS.Start_date <= ReportMonths.ReportMonth) AND
  (MEMBERSHIPS.End_date > ReportMonths.ReportMonth)
GROUP BY
  ReportMonths.ReportMonth;
选择
ReportMonth.ReportMonth,
计数(*)
从…起
报告月份、会员资格
哪里
(MEMBERSHIPS.Start_date ReportMonths.ReportMonth)
分组
ReportMonths.ReportMonth;
免责声明

1) 我现在手头没有MySQL,所以无法测试代码。如果有语法错误,请原谅。不过,它应该给你一个解决问题的一般方法

2) 如果您有数百万行,该解决方案可能会很慢,或者可能会让MySQL崩溃,因为它必须首先构建两个表的叉积。如果是这种情况,我们可以构造一个更复杂的查询,它的性能更好。告诉我们你是否有兴趣

免责声明结束

上述解决方案将把所讨论的月份作为日期返回。如果您不想这样做,那么
选择年份(ReportMonths.ReportMonth)、月份(ReportMonths.ReportMonth),…
而不是
选择ReportMonths.ReportMonth,…

如果您不想使用第二个表,那么恐怕您必须编写一个存储过程或后端应用程序,它每年和每月循环一次,并在每个循环中选择在当前年/月之前和之后开始和结束的行数,然后将该数写在某处,可能是另一个表或数组,用于进一步处理


其优点是,数据库不必在两个表之间构建叉积;缺点是这不是一个单一的查询解决方案。

考虑处理应用程序代码中的数据显示问题。@草莓这就是我所倾向的。。。我当前的解决方案使用。。。想进一步探索SQL,因为它不是我的强项…在这种情况下,在我看来,您当前的解决方案是正确的方法。感谢这个精心制定的答案。。。我试图找到一种更具表现力的方式。我发现创建这种数据会产生某种技术债务。。。当你看代码时,你会想知道那是什么,当你看数据库时,你会想知道那张表是用来做什么的。。。代码正在做什么并不明显。。。我讨厌在我的代码中留下这个…那么你也许可以把第二个表变成一个临时表。这样,它就不会永远挂在数据库中。或者,您可以编写一个存储过程或后端应用程序,其工作方式与我的答案的最后一部分中所述的类似。最后,我承认我可能没有为新表或其列选择最佳名称;如果指定有意义的名称,可能会得到可接受的结果。您还可以在新表中为月份和年份使用两列,并相应地更改代码。这样,新表的用途应该非常清楚了。尽管我最终在应用程序代码中使用了它,但我还是接受了答案。。。谢谢你的时间和深思熟虑的回答…非常感谢。我可能也会这样做。