इस तरह की समस्याओं को हल करना आसान होता है, यदि आपके पास सभी तिथियों के साथ एक कैलेंडर तालिका है जिसकी आपको आवश्यकता है। यदि आपके पास ऐसी कोई तालिका नहीं है, तो आप इसे इस तरह की क्वेरी के साथ बना सकते हैं:
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
यह 1900-01-01 से 2173-10-15 (100K दिन) की तारीखों के साथ एक तालिका बनाएगा और केवल 2.5 एमबी की खपत करेगा। आप इसे अपनी आवश्यकताओं के अनुसार समायोजित कर सकते हैं।
कैलेंडर तालिका का उपयोग करके आप तीन-महीने की सीमाएँ प्राप्त कर सकते हैं:
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'
परिणाम:
| 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 |
यदि आप वास्तव में 90 दिनों के अंतराल जैसी किसी चीज़ का उपयोग करना चाहते हैं, तो इसे समायोजित करें।
अब आप जो चाहते हैं उसे प्राप्त करने के लिए लॉगिन तालिका के साथ बाएं जुड़ना आसान है:
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
http://sqlfiddle.com/#!9/d1bb0/3