3

我有一个表格,可以跟踪用户与客户记录的交互。我想跟踪用户每次“触摸”的持续时间,即每次我们需要访问客户记录时每个用户花费的时间。通过使用 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

提前感谢您提供的任何帮助。我一直在研究岛屿和差距,试图解决这个困境,但我仍然无法弄清楚。

4

3 回答 3

3

请试试这个。SQL小提琴

;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
于 2012-10-24T17:03:59.417 回答
0

您可以在报表中添加和填充“sessionID”字段吗?那么它可以很简单:

select     sessionId, datediff(second, min(time),max(time)) 
from       Trip_History_reporting 
group by   sessionId
于 2012-10-24T12:03:17.597 回答
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
于 2012-10-24T13:31:53.203 回答