0

我正在尝试编写一个查询,该查询返回具有唯一人员 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 分钟范围对这些记录进行排名.

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

4

2 回答 2

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 分钟之内。这听起来像你试图做的。

于 2011-10-06T18:47:21.520 回答
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 
于 2011-10-06T14:22:26.973 回答