【问题标题】:Working Out The Time Difference Between Two Rows On Multiple Occurances计算出多次出现的两行之间的时间差
【发布时间】:2020-03-06 09:50:26
【问题描述】:

我正在研究什么将是一个新函数,但我正在尝试了解如何计算每次出现在另外两列中的值时两行之间的时间差(prev_value,current_value)。然后将差值包含在总和中,作为每个 ID 的最终值。

下面的示例是表格的一小部分,所以如果我们使用 ID 194422,希望我能明白我的意思。

我要计算的 Datediff 将介于具有 Current_Value 12026 和 Prev_Value 12026 的每条记录之间。因此,在前 2 行之间,我预计会有 3 分钟的差异,而在第 3 行和第 4 行之间,我预计会有4分钟的差异。

如果该行包含 12026 的 current_value 和 prev_value,那么我也会在时间中包含这个,所以在第 13、14、15 行,我预计第 13 行和第 15 行之间会有 9 分钟的差异。

然后我会按 ID 对这些结果进行分组和汇总。

ROWID|  ID   | Columnname | prev_value |     current_value  |      OperationTime


1    |197684 |  STATUSID  |    1       |     12026          |     2020-02-11 13:37:00.0010
2    |197684 |  STATUSID  | 12026      |       1            |     2020-02-11 13:40:00.000
3    |197684 |  STATUSID  |    1       |     12026          |     2020-02-11 13:44:00.000
4    |197684 |  STATUSID  | 12026      |       1            |     2020-02-11 13:48:00.000
5    |198662 |  STATUSID  |    1       |     12026          |     2020-02-24 15:10:00.000
6    |198662 |  STATUSID  | 12026      |       1            |     2020-02-24 15:20:00.000
7    |198662 |  STATUSID  |    1       |     12026          |     2020-02-24 15:23:00.000
8    |198662 |  STATUSID  | 12026      |       1            |     2020-02-24 15:41:00.000
9    |198662 |  STATUSID  |    1       |     12026          |     2020-02-24 16:24:00.000
10   |198662 |  STATUSID  | 12026      |       1            |     2020-02-24 17:05:00.000
11   |194422 |  STATUSID  |    1       |     12026          |     2020-02-25 09:04:00.000
12   |194422 |  STATUSID  | 12026      |       8            |     2020-02-25 09:07:00.000
13   |198662 |  STATUSID  |    1       |     12026          |     2020-02-26 15:32:00.000
14   |198662 |  STATUSID  | 12026      |     12026          |     2020-02-26 15:40:00.000
15   |198662 |  STATUSID  | 12026      |       1            |     2020-02-26 15:41:00.000
16   |194422 |  STATUSID  |    1       |     12026          |     2020-03-02 16:06:00.000
17   |194422 |  STATUSID  | 12026      |       8            |     2020-03-02 16:15:00.000

最终的结果是:

      RowID |  TimeSpent(Mins)

    194422  |     9
    197684  |     7
    198662  |     78

我现在尝试了几种不同的方法,但记录要么丢失,要么检索的时间不正确。

我在 CTE 上查看了带有 INNER 和 LEFT JOIN 和 OUTER JOIN 的 CTE,我尝试了两个 CTE,我查看了所有示例中的 LAG、RANK 和 ROW_NUMBER()。

下面的脚本可以正常工作,但它没有提取我所有的结果,在这个例子中它错过了 ID 194422。

DECLARE @STATUSID INT 
SET @STATUSID = 12026 

;WITH CTE
     AS (SELECT prev_value, 
                current_value, 
                OPERATIONTIME,
                ROWID,
                ID,
            DENSE_RANK () OVER (PARTITION BY prev_value ORDER BY operationtime) AS ROWNUMBER  
         FROM   AUDITREVIEW
         WHERE  columnname = 'STATUSID' 
                AND ( current_value = @STATUSID 
                       OR prev_value = @STATUSID )    
                ) 

SELECT *,
    DATEDIFF(MINUTE,  CTE2.cte2OPERATIONTIME, CTE1.operationtime) as t
    INTO #Temp
FROM 
    CTE AS CTE1
OUTER APPLY 
        (SELECT  top 1
           prev_value as cte2prev_value, 
                current_value cte2current_value, 
                OPERATIONTIME cte2OPERATIONTIME,
                ROWID cte2rowID,
                ID cte2ID,
                DENSE_RANK () OVER ( ORDER BY operationtime) AS cte2ROWNUMBER 
            FROM CTE 
            WHERE CTE.ID = CTE1.ID 
            AND CTE.PREV_VALUE = CTE1.CURRENT_VALUE
            AND CTE.ROWNUMBER < CTE1.ROWNUMBER
            ORDER BY CTE.OPERATIONTIME DESC
            ) CTE2

--WHERE CTE1.WORKORDERID = 194422


SELECT SUM(t), ID
FROM #Temp
WHERE cte2prev_value <> @STATUSID
GROUP BY ID

DROP TABLE #Temp

【问题讨论】:

  • 我觉得最后一条记录应该是17 |194422 |状态ID | 12026 | 1 | 2020-03-02 16:15:00.000 而不是 17 |194422 |状态ID | 12026 | 8 | 2020-03-02 16:15:00.000

标签: sql-server common-table-expression datediff self-join


【解决方案1】:

尝试以下方法:

SELECT a1.ID, 
       SUM(DATEDIFF(MINUTE, a1.OperationTime, a2.OperationTime)) Time_Spent_in_Minutes
FROM AUDITREVIEW a1
     JOIN AUDITREVIEW a2 ON a2.ID = a1.ID
                            AND ((a1.ROWID = a2.ROWID)
                                 OR (a1.ROWID + 1 = a2.ROWID))
WHERE(a1.current_value = 12026 AND a2.prev_value = 12026)
     AND ((a1.prev_value = 1 AND a2.current_value = 1)
          OR (a1.current_value = 12026 AND a1.prev_value = 12026)
          OR (a2.current_value = 12026 AND a2.prev_value = 12026))
GROUP BY a1.ID
ORDER BY 1;

db<>fiddle demo

【讨论】:

  • 嗨,Sacse,感谢您的回答,脚本似乎没有根据您的建议得出任何结果。
  • 您是否还检查了 dbfiddle 示例中的结果(我在答案中提供了指向该链接的链接)?
猜你喜欢
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
  • 2018-04-03
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多