2011-10-06 54 views
0

考虑这个表结构。如何按日期跨度进行分组?

Key  ID  VISITDATE 
1   1  2011-01-07 
2   1  2011-01-09 
3   2  2011-01-10 
4   1  2011-01-12 
5   3  2011-01-12 
6   1  2011-01-15 
7   2  2011-01-21 
9   1  2011-02-28 
10  2  2011-03-21 
11  1  2011-01-06 

我需要让所有的ID,重点,分(VisitDate)其中VisitDate是在10天内跨越吗?如果你有10天之内一排两次访问需要在那里的结果。

结果

KEY  ID  VISITDATE 
11  1   2011-01-06 
3   2   2011-01-10 
5   3   2011-01-12 
7   2   2011-01-21 
9   1   2011-02-28 
10   2   2011-03-21 

可以这样没有自我来完成连接。我有一个查询,它会自动连接ID上的表并检查datediff.is是否有更好的解决方案?我们可以在这里使用递归CTE吗?

编辑

身高可以使用索引上日期列的解决方案

+1

如果您有访问,请等待8天,再次访问,等待8天,再次访问?应该有两组,对吗?但是,哪两行?有两种方法来执行分组(AB)C或A(BC),并且您没有指定您想要的。或者我错过了什么? –

+0

每10天的跨度如何定义?从第一次访问开始? – Mike

+0

@迈克耶。从第一次访问开始... –

回答

2

是一个CTE将很好地工作,这个(一切与我是最近的CTE)...

;WITH TenDayVisits 
AS (

SELECT 
     ID 
     ,MIN(VisitDate) AS VisitDate 
    FROM Visits 
    GROUP BY ID 
    UNION ALL 
    SELECT 
     t.ID 
     ,v.VisitDate 
    FROM Visits AS v 
    JOIN TenDayVisits AS t ON v.ID = t.ID    
     AND DATEDIFF(dd,t.Visitdate,v.VisitDate) > 10 
) 

SELECT 
    DISTINCT 
    v.[key] 
    ,t.id 
    ,t.VisitDate 
FROM TenDayVisits as T 
JOIN Visits AS v ON t.id = v.id 
    AND t.VisitDate = v.VisitDate 
+0

谢谢。我把DISTINCT扔进去了,因为我得到了一些重复的东西......你也许可以调整CTE的递归部分来摆脱困惑,但是DISTINCT也可以。 – Wil

+0

是否有办法删除键盘查找(在执行计划)出于性能原因......修改查询,以便它可以使用日期索引 –

+0

这是很难回答,不知道你有什么索引。如果你在[Key]上有一个聚集索引,你可能想把它加入到CTE中,将它加入访问,而不是id和日期,但这可能会让CTE返回正确的值。还有一个关于'DATEDIFF'和索引的错误:http://connect.microsoft.com/SQLServer/feedback/details/630583/incorrect-estimate-with-condition-that-includes-datediff – Wil