SQL Select记录以小时分隔

时间:2011-10-05 19:05:38

标签: tsql rank

我正在尝试编写一个查询,该查询返回具有唯一人员ID,地点ID以及仅在60分钟内访问的第一次出现的值。

这就是我需要的......

SELECT * FROM
(
SELECT  
    RANK() OVER (PARTITION BY A.PersonId, A.PlaceId,
    DATEDIFF(hh, A.Visit_Datetime, GETDATE()) ORDER BY A.Visit_Datetime) AS RNK,
    A.RecordId,
    A.PersonId,
    A.PlaceId
FROM
    Table A
) A
WHERE
    A.Rnk = 1

问题在于如果一个人在上午10:50访问,然后在上午11:10创建第二个记录,则两个记录都被排名为1.我需要的是按人,地点和60分钟范围。

我希望这是有道理的。谢谢你的帮助。

2 个答案:

答案 0 :(得分:0)

试试这个

SELECT * FROM 
( 
SELECT   
    RANK() OVER (PARTITION BY A.PersonId, A.PlaceId, 
    DATEDIFF(hh, 0, A.Visit_Datetime) ORDER BY A.Visit_Datetime) AS RNK, 
    A.RecordId, 
    A.PersonId, 
    A.PlaceId 
FROM 
    Table A 
) A 
WHERE 
    A.Rnk = 1 

答案 1 :(得分:0)

目前,您正在按固定小时数进行分组,由当前时间决定。 你想要一个移动的小时。这不能基于当前日期或像0这样的文字。 这意味着您需要将所有可能的时间分组。幸运的是,您不需要全部计算它们。 而是将每个访问时间的小时数分组。即10:50与10:50至11:50和11:10之间的所有访问分组,访问时间为11:10至12:10

FROM Table as A 
JOIN Table as B ON A.Visit_Datetime BETWEEN DATEADD(HOUR,-1,B.Visit_Datetime) 
    AND B.Visit_Datetime 

这将产生重叠组,类似于具有多个等级1。 B连接到所有出现但您想要第一次出现。 将事件组合在一起并使用min来获得第一个。 像这样:

SELECT DISTINCT MIN(A.Visit_Datetime) as InitVisit, B.RecordId, B.PersonId, B.PlaceID, 
FROM Table as A 
JOIN Table as B ON A.Visit_Datetime BETWEEN DATEADD(HOUR,-1,B.Visit_Datetime) AND B.Visit_Datetime 
AND B.RecordId = A.RecordId AND B.PersonId = A.PersonId AND B.PlaceID = A.PlaceId 
GROUP BY B.RecordId, B.PersonId, B.PlaceID, B.Visit_Datetime 

这应该为您提供每个记录,人物,地点的访问时间。访问期实际上是任何长度,但每次出现都是在另一次出现的60分钟内。这听起来就像你想要做的那样。