Problemas como esse são mais fáceis de resolver, se você tiver uma tabela de calendário com todas as datas que precisa. Se você não tiver essa tabela, poderá criá-la com uma consulta como esta:
create table `calendar` (
`date` DATE NOT NULL,
PRIMARY KEY (`date`)
)
select DATE_ADD('1900-01-01',INTERVAL t4.c*10000 + t3.c*1000 + t2.c*100 + t1.c*10 + t0.c DAY) as `date`
from
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t0,
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t1,
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t2,
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t3,
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t4
Isso criará uma tabela com datas de 1900-01-01 a 2173-10-15 (100K dias) e consumirá apenas cerca de 2,5 MB. Você pode ajustá-lo às suas necessidades.
Usando a tabela de calendário, você pode obter intervalos de três meses:
select
DATE_FORMAT(date_sub(c.date, INTERVAL 1 day), '%Y-%m') as month,
date_sub(c.date, INTERVAL 3 month) as first_day,
date_sub(c.date, INTERVAL 1 day) as last_day
from calendar c
where day(c.date) = 1
and c.date between '2015-02-01' and '2015-09-01'
Resultado:
| month | first_day | last_day |
| 2015-01 | 2014-11-01 | 2015-01-31 |
| 2015-02 | 2014-12-01 | 2015-02-28 |
| 2015-03 | 2015-01-01 | 2015-03-31 |
| 2015-04 | 2015-02-01 | 2015-04-30 |
| 2015-05 | 2015-03-01 | 2015-05-31 |
| 2015-06 | 2015-04-01 | 2015-06-30 |
| 2015-07 | 2015-05-01 | 2015-07-31 |
| 2015-08 | 2015-06-01 | 2015-08-31 |
Ajuste-o, se você realmente quiser usar algo como intervalos de 90 dias.
Agora é uma simples junção esquerda com a tabela de login para obter o que você deseja:
select i.month as `Date`, count(distinct l.user_id) as `Active users`
from (
select
date_format(date_sub(c.date, interval 1 day), '%Y-%m') as month,
date_sub(c.date, interval 3 month) as first_day,
date_sub(c.date, interval 1 day) as last_day
from calendar c
where day(c.date) = 1
and c.date between '2015-02-01' and '2015-09-01'
) i
left join login_table l on l.login_date between i.first_day and i.last_day
group by i.month
https://sqlfiddle.com/#!9/d1bb0/3