这不是用一句话描述的最简单的查询,这就是为什么标题可能不是最好的。
基本上我有登录日志。此日志如下所示:
ContactId, LocationId, TimeStamp
这些代表在指定时间在某个地点看到的联系人(注册人)。
我想要做的就是选择一个日期时间窗口,对于该窗口中的每一天,我想进行第一次登录,然后进行最后一次登录并计算出小时数差异。这种小时差异应该会影响总体总数,估算联系人在该月份在该地点所花费的总时间。
显然可以忽略联系人未被看到的日子,并且不应该使用只有一次联系人的日子,因为无法计算差异。
我知道如何找出两个小时之间的差异:
select DATEDIFF(HOUR, datetime1, datetime2) as hoursestimate
但我不确定如何:
根据第一个和最后一个看到的差异,我会在整个时间段内累计累计小时数,我将使用我的联系表执行联接以通过此TotalHours列获取他们的姓名和顺序,所以希望最终表我希望从查询返回的内容如下:
Id FirstName LastName TotalHours
35 Bob Bobberson 65
40 Jim Jimmerson 63
2 Harry Harrison 54
我已经失去了第1步和第2步。有什么想法吗?
答案 0 :(得分:2)
我想你想要两个聚合:
select contactid, sum(hoursestimate) as total
from (select contactid, cast(TimeStamp as date) as dte,
DATEDIFF(HOUR, min(TimeStamp), max(TimeStamp)) as hoursestimate
from t
where TimeStamp >= @start and TimeStamp < @end
group by contactid, cast(TimeStamp as date)
) t
group by contactid;
答案 1 :(得分:1)
有几种不同的技术可以帮助你。
CAST将允许您相互删除日期时间戳的日期和时间部分。这对于从同一天,但不同时间一起分组多个记录非常方便。
HAVING可用于过滤掉一天只有记录的联系人。这可以通过计算贡献记录的数量,并删除低于阈值的记录。
这个例子结合了这些技术:
WITH SampleDate AS
(
/* Lets make some records to experiment with.
*/
SELECT
r.*
FROM
(
VALUES
(1, 1, '2015-01-01 09:00:00.000'),
(1, 1, '2015-01-01 12:00:00.000'),
(1, 1, '2015-01-01 17:00:00.000'),
(2, 1, '2015-01-01 09:00:00.000')
) AS r(ContactId, LocationId, [TimeStamp])
)
SELECT
ContactId,
LocationId,
CAST([TimeStamp] AS DATE) AS [Day],
MIN(CAST([TimeStamp] AS TIME)) AS FirstSeenTime,
MAX(CAST([TimeStamp] AS TIME)) AS LastSeenTime,
DATEDIFF(
HOUR,
MIN(CAST([TimeStamp] AS TIME)),
MAX(CAST([TimeStamp] AS TIME))
) AS HoursEstimate
FROM
SampleDate
GROUP BY
ContactId,
LocationId,
CAST([TimeStamp] AS DATE) -- Removing the time allows us to create 1 record per day.
HAVING
COUNT(*) > 1 -- Make sure we've seen the contact at least twice.
;