我可以只为一个新人计算几个月的费用吗?

时间:2019-05-10 15:37:58

标签: mysql sql

我想统计一下一年中参加活动的人数。每个人在MariaDB中都有一个唯一的ID,我可以使用COUNT(DISTINCT MEMBER_ID)并按事件月份进行分组来获得每个月的总数。但是,我想知道每个月有多少人是新来的(例如,参加了第一场比赛),还有多少人正在返回。

例如,如果有一个这样的表...

EVENT_ID    MEMBER_ID    EVENT_DATE

1001        100          1/1/2019
1001        123          1/1/2019
1001        222          1/1/2019
1002        100          1/4/2019
1002        123          1/4/2019
1002        333          1/4/2019
1003        100          2/12/2019
1003        444          2/12/2019
1004        123          2/20/2019
1004        555          2/20/2019

...此代码将为我提供每月参加会议的人数。

SELECT MONTH(EVENT_DATE) as EVENT_MONTH, COUNT(DISTINCT MEMBER_ID) as ID_COUNT FROM `table` 

WHERE YEAR(EVENT_DATE) = YEAR(CURRENT_TIMESTAMP)

GROUP BY MONTH(EVENT_DATE)

喜欢这个...

EVENT_MONTH    ID_COUNT 
1              4
2              4

至少,我想知道每个月有多少新朋友,所以

EVENT_MONTH    ID_COUNT 
1              4
2              2

但是,如果可能的话,我希望统计一下1月份来的人继续参加2月份的人数,以及2月份来的人参加3月份的人数等等。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

选择带有min(eventDate)的成员ID到新表中。然后,您可以对新表使用另一个查询来确定它是否是成员的第一个事件。

答案 1 :(得分:0)

您可以将每个月度活动选择到一个临时表中(最接近CTE的表),以及会员ID和标志(frst)来告诉您,这是否是“第一次”访问:

CREATE TEMPORARY TABLE IF NOT EXISTS tmp AS( 
  select member_id mid ,year(event_date)*100+month(event_date) yemo,
  CASE WHEN (select min(event_date) 
             from tbl where member_id=t1.member_id)=event_date 
       THEN 1 END frst
  FROM tbl t1
);

一旦有了此(临时)表,就可以按月分组并计算该月内“首次”访问的(区别!)成员:

SELECT count(distinct mid) cnt,yemo from tmp where frst=1 group by yemo

请注意,我将每个日期的year()month()合并为一个值yemo,因为仅一个月在一个日历年中是唯一的。

您可以在此处查看有效的演示:https://rextester.com/GNBG69033

您得到的结果如下:

    yemo    cnt
1   201901  4
2   201902  2

修改

如果我们想知道首次访问后一个月内再次访问的会员人数,我们需要一种稍微完善的方法:

CREATE TABLE tmp AS( 
  select member_id mid ,year(event_date) ye,month(event_date) mo,
         (year(event_date)-2000)*12+month(event_date) yemo,
         CASE WHEN (select min(event_date) from tbl
                    where member_id=t1.member_id)=event_date 
              THEN 1 END frst
  from tbl t1
);

select ye,mo, sum(cfrst) firsts, sum(pfrst) seconds FROM (
 SELECT c.ye, c.mo, c.yemo cyemo, c.mid, max(c.frst) cfrst, max(p.frst) pfrst
 FROM tmp c 
 LEFT JOIN tmp p ON p.mid=c.mid and p.yemo=c.yemo-1 
 group by c.yemo, c.mid 
) t 
group by ye,mo
order by ye,mo

我们现在需要一个“适当的”表,而不是临时表,因为它需要多次引用。 yemo列现在的定义有所不同,因此我们可以更轻松地链接到“上个月”。

结果如下:

    ye      mo  firsts  seconds
1   2019    1   4       NULL
2   2019    2   2       2

https://rextester.com/CFNT26170