Вы можете выбрать отдельные ежемесячные события во временной таблице (ближайшей к CTE), вместе с идентификаторами участников и флагом (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