我正在尝试编写一个查询,该查询返回具有唯一人员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分钟范围。
我希望这是有道理的。谢谢你的帮助。
答案 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分钟内。这听起来就像你想要做的那样。