我认为,您的特定应用程序使这变得非常简单。如果在“n”天的间隔中有“n”个不同的日期,那么这些“n”个不同的日期必须是连续的。
滚动到底部以获取仅需要公用表表达式并更改为 PostgreSQL 的通用解决方案。(开玩笑。我是在 PostgreSQL 中实现的,因为我时间不够。)
create table ForumPost (
  ID integer primary key,
  UserID integer not null,
  post_date date not null
);
insert into forumpost values
(1, 1, '2013-01-15'),
(2, 1, '2013-01-16'),
(3, 1, '2013-01-17'),
(4, 1, '2013-01-18'),
(5, 1, '2013-01-19'),
(6, 1, '2013-01-20'),
(7, 1, '2013-01-21'),
(11, 2, '2013-01-15'),
(12, 2, '2013-01-16'),
(13, 2, '2013-01-17'),
(16, 2, '2013-01-17'),
(14, 2, '2013-01-18'),
(15, 2, '2013-01-19'),
(21, 3, '2013-01-17'),
(22, 3, '2013-01-17'),
(23, 3, '2013-01-17'),
(24, 3, '2013-01-17'),
(25, 3, '2013-01-17'),
(26, 3, '2013-01-17'),
(27, 3, '2013-01-17');
现在,让我们看看这个查询的输出。为简洁起见,我正在查看 5 天的间隔,而不是 30 天的间隔。
select userid, count(distinct post_date) distinct_dates
from forumpost
where post_date between '2013-01-15' and '2013-01-19'
group by userid;
USERID  DISTINCT_DATES  
1       5
2       5
3       1
对于符合条件的用户,该 5 天间隔内的不同日期数必须为 5,对吗?所以我们只需要将该逻辑添加到 HAVING 子句中。
select userid, count(distinct post_date) distinct_dates
from forumpost
where post_date between '2013-01-15' and '2013-01-19'
group by userid
having count(distinct post_date) = 5;
USERID  DISTINCT_DATES  
1       5
2       5
更通用的解决方案
说真的没有道理,如果你从 2013 年 1 月 1 日到 2013 年 1 月 31 日每天发帖,你已经连续 30 天发了 2 次。相反,我希望时钟在 2013 年 1 月 31 日重新开始。我很抱歉在 PostgreSQL 中实现;稍后我将尝试在 T-SQL 中实现。
with first_posts as (
  select userid, min(post_date) first_post_date
  from forumpost
  group by userid
), 
period_intervals as (
  select userid, first_post_date period_start, 
         (first_post_date + interval '4' day)::date period_end
  from first_posts
), user_specific_intervals as (
  select 
    userid, 
    (period_start + (n || ' days')::interval)::date as period_start, 
    (period_end + (n || ' days')::interval)::date as period_end 
  from period_intervals, generate_series(0, 30, 5) n
)
select userid, period_start, period_end, 
       (select count(distinct post_date) 
        from forumpost
        where forumpost.post_date between period_start and period_end
          and userid = forumpost.userid) distinct_dates
from user_specific_intervals
order by userid, period_start;