我有一张表跟踪用户与客户记录的互动情况。我想跟踪用户每次“触摸”的持续时间,即每次我们需要访问客户记录时每个用户花费的时间。通过使用ROW_NUMBER()OVER(PARTITION BY | ORDER BY),我已经掌握了基础知识。我无法得到我的豌豆大脑的问题是,当这些触摸是连续的,但是相隔很长时间时,如何分离两个不同的用户触摸。我不知道我已经清楚地解释了这一点,但下面的例子应该澄清:
以下是我可以成功查询的数据示例:
DATE TIME USER
11/17/2011 1:30:47 ZDBatch
11/17/2011 1:32:40 ZDBatch
12/13/2011 10:39:46 EMSZC27
12/13/2011 10:45:48 EMSZC27
所需的结果集是
DURATION (MIN) USER
1.883 ZDBatch
6.033 EMSZC27
并通过以下查询实现(请注意,我在上面的示例中留下了一些列):
; WITH CTE1 AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY thr.[tdate], thr.[job], thr.[who], thr.[moddate] ORDER BY thr.[moddate]) AS RowNo,
thr.[tdate], thr.[job], thr.[moddate], thr.[modtime], thr.[seq], thr.[who],
thr.[description], thr.[histtype], thr.[attachment], thr.[data1], thr.[data2]
FROM Trip_History_Reporting thr
WHERE thr.[tdate] = '2011-10-24' --AND thr.[job] IN ('0653-A', '0128-A')
AND LEFT(thr.[description], 8) <> 'Recalled'
AND (LEFT(thr.[who],5) = 'EMSZC' OR thr.[who] = 'ZDBatch')
--ORDER BY thr.[moddate], thr.[modtime]
)
SELECT tdate, job, MIN(RowNo), MAX(RowNo), MIN(modtime) AS [Start], MAX(modtime) AS [End],
CAST(CAST(DATEDIFF(SECOND, MIN(modtime), MAX(modtime)) AS DECIMAL(6,0))/60 AS DECIMAL(8,2)) AS [Duration (Min)],
who, moddate
FROM CTE1
GROUP BY tdate, job, who, moddate
以下是我无法成功查询的数据示例(同一用户的连续不同触摸):
DATE TIME USER
11/1/2011 6:34:48 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/15/2011 11:08:32 EMSZC34
11/15/2011 11:09:14 EMSZC34
11/15/2011 11:09:14 EMSZC34
11/15/2011 11:09:14 EMSZC34
11/15/2011 11:09:14 EMSZC34
11/15/2011 11:09:14 EMSZC34
当在第一次触摸结束和第二次触摸开始之间经过“显着”时间时出现问题(为了论证,如果在触摸之间经过一小时,那些是不同的触摸)。
上述数据所需的结果集是
DURATION (MIN) USER
0.333 EMSZC34
0.7 EMSZC34
这看起来很简单,但我无法弄清楚。提前感谢任何想法,建议,直截了当的嘲弄。
我为延迟回复而道歉。我意识到这个小组正在提供免费帮助,我不打算通过快速回复来利用它。我会尽力不让这种情况再次发生。
根据EricZ的要求,以下是具有所需输出的示例:
DATE TIME USER
11/1/2011 6:34:48 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/1/2011 6:35:08 EMSZC34
11/15/2011 11:08:32 EMSZC34
11/15/2011 11:09:14 EMSZC34
11/15/2011 11:09:14 EMSZC34
11/15/2011 11:15:24 EMSZC34
11/15/2011 11:26:38 EMSZC34
11/15/2011 11:34:55 EMSZC34
11/15/2011 11:36:22 EMSZC34
期望的输出:
DURATION (MIN) USER
0.333 EMSZC34
27.833 EMSZC34
提前感谢您提供的任何帮助。为了解决这个难题,我一直在研究岛屿和差距,但我仍然无法弄明白。
答案 0 :(得分:3)
请试试这个。 SQL Fiddle
;WITH c1 AS (
SELECT DISTINCT CAST(LEFT(CONVERT( VARCHAR(20),moddate,112),10)+ ' ' + modtime AS DATETIME)as moddate ,moduser
FROM Trip_History_Reporting
)
, c2 AS (
SELECT moddate,moduser,ROW_NUMBER() OVER (PARTITION BY moduser ORDER BY moddate) as row_no
FROM c1
)
, c3 AS (
SELECT c.moddate as startdate, cc.moddate as enddate, DATEDIFF(SECOND,c.moddate,cc.moddate) as diff,c.moduser
FROM c2 c
INNER JOIN c2 cc
ON c.moduser= cc.moduser
AND c.row_no = cc.row_no -1
)
SELECT *,diff/60.00 as diff_in_min
FROM c3
WHERE diff <= 60*60 -- an hour in second
<强>更新强> 根据您更新的问题,请使用以下查询
WITH c1 AS (
SELECT DISTINCT CAST(LEFT(CONVERT( VARCHAR(20),moddate,112),10)+ ' ' + modtime AS DATETIME)as moddate ,moduser
FROM Trip_History_Reporting
)
, c2 AS (
SELECT moddate,moduser,(SELECT MAX(cc.moddate) FROM c1 cc WHERE cc.moddate <= DATEADD(hour,1,c.moddate) AND cc.moddate > c.moddate AND c.moduser = cc.moduser) AS endtime
FROM c1 c
)
, c3 AS (
SELECT moduser, MIN(moddate) as [start],endtime AS [end]
FROM c2
WHERE endtime IS NOT NULL
GROUP BY moduser,endtime
)
SELECT *,DATEDIFF(SECOND,[start],[end])/60.0 as diff_in_min
FROM c3
答案 1 :(得分:0)
您是否可以在报告表中添加并填充“sessionID”字段?然后就可以这么简单:
select sessionId, datediff(second, min(time),max(time))
from Trip_History_reporting
group by sessionId
答案 2 :(得分:0)
是伪TSQL
语法不正确
订购所有行。
加入RowNumber + 1.
只使用均匀。
WITH Ordered AS
(
SELECT DATE, TIME, USER
ROW_NUMBER() AS RowNumber
FROM Trip_History_Reporting
)
select O1.USER, (O2.TIME - O1.TIME)
from order O1
join order O2
on O2.RowNumber = O1.RowNumber + 1
where O1%2 = 0