确定SQL Server 2014中样本保持不变的时间窗口的有效方法

确定SQL Server 2014中样本保持不变的时间窗口的有效方法,sql,sql-server,sql-server-2014,Sql,Sql Server,Sql Server 2014,考虑以下4人的数据: ID Date (DMY) 1 2014-12-30 2 2014-12-30 3 2014-12-30 4 2014-12-30 1 2014-12-31 2 2014-12-31 3 2015-01-01 1 2015-01-01 3 2015-01-02 1 2015-01-02 3 2015-01-03 1 2015-01-03 4 2015-01-03 现在我想做的是每天检测ID组的变化。起初,当我想到它时,这是一个相对容易的问题,但它

考虑以下4人的数据:

ID Date (DMY)
1  2014-12-30
2  2014-12-30
3  2014-12-30
4  2014-12-30
1  2014-12-31
2  2014-12-31
3  2015-01-01
1  2015-01-01
3  2015-01-02
1  2015-01-02
3  2015-01-03
1  2015-01-03
4  2015-01-03
现在我想做的是每天检测ID组的变化。起初,当我想到它时,这是一个相对容易的问题,但它非常困难,因为:

2014年12月30日,我们看到有4人。 在2014年12月31日,也应该是4人,因为ID=3和ID=4的人不做交易,但我们可以在数据中稍后检测他们的活动,这意味着他们仍然在样本中。 截至2015年1月1日,只有3人,ID=1,ID=3,ID=4。ID=2在其余数据中不再执行任何操作。 截至2015年1月2日,共有3人。 截至2015年1月3日,仍有3人。 所以我希望SQL返回日期:2014-12-30到2014-12-31,2015-01-01到2015-01-03

以我的拙见,这是非常困难的,我不知道如何解决这个问题。TSQL甚至可以处理此类问题吗


谢谢

所以,有人从第一次出现到最后一次出现都在数据中。以下是一种累积和的方法:

这项工作是在SQL 2008中完成的 我不能告诉您数据大小的效率,但应该不会有任何问题

WITH dateGroup(gDate)
AS (
    -- SEE HOW MANY DIFFERENT DATES ARE THERE
    SELECT DISTINCT DATE
    FROM [dbo].[testData] 
), userActivity (id, dBegin, dEnd)
AS (
    -- SEE THE ACTIVITY WINDOW FOR EACH USER
    SELECT ID, MIN(DATE), MAX(DATE)
    FROM [dbo].[testData] 
    GROUP BY ID
), rangeDate ( gDate, users)
AS (
    -- SEE WHICH USERS ARE ACTIVE ON EACH DATE
    SELECT *
    FROM dateGroup as p OUTER APPLY 
        (SELECT STUFF(( SELECT ';' + CAST(a.id AS VARCHAR(10) )
           FROM userActivity AS a
          WHERE p.gDate BETWEEN a.dBegin AND a.dEnd
          ORDER BY a.id
            FOR XML PATH('') ), 1,1,'') AS users ) AS f
), activityWindow (users) 
AS (
    -- DETECT WHEN THE ACTIVE GROUP CHANGE
    SELECT distinct users
    FROM rangeDate
)
-- SEE THE RANGE FOR EACH GROUP.
SELECT *
FROM activityWindow as p OUTER APPLY 
        (SELECT STUFF(( SELECT ' ; ' + CAST(a.gDate AS VARCHAR(10) )
           FROM rangeDate AS a
           WHERE p.users = a.users    
        FOR XML PATH('') ), 1,1,'') AS activity_window ) AS f
不仅你有日期范围。 您有哪个用户在该范围内处于活动状态。你可以分为两部分; 而且你可以看到所有的日子,所以如果周日没有数据,你可以看到它。 如果只想开始和结束,你就要分开;第一次和最后一次约会

试试这个:

with c as(
  select min(d) as d from t group by id
  union 
  select max(d) as d from t group by id),
u as(
  select * from c
  union all
  select dateadd(dd, 1, d) from c
  where d <> (select max(d) from c) and d <> (select min(d) from c)),
r as(select d, row_number() over(order by d) rn from u)
select r1.d, r2.d from r r1
join r r2 on r1.rn + 1 = r2.rn
where r2.rn % 2 = 0
如果我是正确的,我们的想法是选择高峰日期,即添加某人或某人的最后一天。这是在第一个cte中完成的。第二个cte用高峰日期的下一个日期填充高峰日期。第三个cte只是为以下连接的行编号,以获得间隔


我不完全确定这是否是正确的逻辑,但它在提供的测试数据上起作用

如果在2015-01-04出现一个新的ID,比如ID=5,会发生什么?在2014-12-31,它也应该是4人,这意味着什么??因为你说我们可以在以后的数据中检测到他们的活动,你是怎么做到的?我真的不明白这个问题。谢谢你的指导,所以如果出现一个新的Id,假设在2015-01-04我们得到一个新的Id,那么样本组会发生变化,因此我们在2015-01-04某个日期得到一个新窗口@JuanCarlosOropeza,样本中仍然有4个人,因为在稍后的日期,我们可以看到ID=4有一些活动,因此他/她仍然在我们的样本中,ID=3也在稍后的日期进行交易。因此每个ID都有一个活动窗口选择MINdate,MAXdate??在这个例子中{1,3,4}有{12-30;01-03}和{2}有{12-30,12-31}亲爱的Juan,你是对的,每个ID确实有一个活动窗口。问题是将其聚合到一个总活动窗口中,换句话说,在该窗口中ID保持不变。如果ID 9、8、7的活动窗口为3天,那么在ID 7停止的第四天,一个新的聚合活动窗口将处于活动状态,因为ID 7不再处于活动状态,我对这些聚合活动窗口感兴趣。我尝试重新生成此查询,但在suminc上发现一个错误,超过了DTear的订单。您确定要使用SQL Server 2014吗?
with c as(
  select min(d) as d from t group by id
  union 
  select max(d) as d from t group by id),
u as(
  select * from c
  union all
  select dateadd(dd, 1, d) from c
  where d <> (select max(d) from c) and d <> (select min(d) from c)),
r as(select d, row_number() over(order by d) rn from u)
select r1.d, r2.d from r r1
join r r2 on r1.rn + 1 = r2.rn
where r2.rn % 2 = 0