t-sql顺序持续时间

时间:2012-10-24 11:55:52

标签: tsql duration sequential

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

提前感谢您提供的任何帮助。为了解决这个难题,我一直在研究岛屿和差距,但我仍然无法弄明白。

3 个答案:

答案 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