计算相邻行之间的时间差
Calculate time difference between adjacent rows
我有以下 table 格式
ID Status Date
16 In Review 2017-07-03 08:23:11.000
16 Approved 2017-07-03 08:23:20.000
16 Approved 2017-07-11 10:34:27.000
我正在尝试获取审查中和批准之间的时间差,应该是 9 秒..
这是我之前 where Gordon 为我提供答案的延续。
这是它的代码
select avg(avg_bid_diff)
from (select bid, avg(diff*1.0) as avg_bid_diff
from (select bid, appid,
datediff(second, min(starttime), max(statustime)) as diff
from t
where appstatus in ('In Review', 'Approved')
group by bid, appid
having count(*) = 2
) ba
group by bid
) b;
问题是,当它考虑最小值和最大值时,我得到第一行和第三行之间的时间差,当只有 2 个状态时,但我需要的是第一次审查和下一次审查之间的时间差批准
谁能告诉我应该如何更改查询以获得下一个批准的时差。
谢谢
这有点棘手,但目前看来效果不错。唯一的限制是对于每个唯一的(BidID,AppID)对,没有或只有一个状态为 'In Review'.
的记录
我对链式 CTE 使用了完全不同的方法:
DECLARE @table TABLE
(
BidID int,
AppID int,
AppStatus nvarchar(20),
StatusTime DATETIME2
);
INSERT INTO @table (BidID, AppID, AppStatus, StatusTime)
VALUES
(1, 1, 'In Review', '2019-01-02 12:00:00'),
(1, 1, 'Approved', '2019-01-02 13:00:00'),
(1, 1, 'Approved', '2019-01-02 13:30:00'),
(1, 2, 'In Review', '2019-01-04 13:00:00'),
(1, 2, 'Approved', '2019-01-04 15:00:00'),
(2, 2, 'Approved', '2019-01-07 14:30:00'),
(2, 2, 'In Review', '2019-01-07 15:00:00'),
(2, 2, 'Approved', '2019-01-07 16:00:00'),
(3, 1, 'In Review', '2019-01-09 13:00:00'),
(4, 1, 'Approved', '2019-01-09 13:00:00');
;WITH OrderedRecords(BidID, AppID, AppStatus, StatusTime, [Order])
AS (
SELECT BidID
,AppID
,AppStatus
,StatusTime
, [Order] = ROW_NUMBER() OVER(PARTITION BY BidID, AppID ORDER BY StatusTime)
FROM @table
),
BidAverage(BidID, AveragePerBid)
AS (
SELECT OR1.BidID, AVG(CAST(DATEDIFF(HOUR, OR1.StatusTime, OR2.StatusTime) AS DECIMAL)) AS AveragePerBid
FROM OrderedRecords OR1
INNER JOIN OrderedRecords OR2
ON OR1.BidID = OR2.BidID AND OR1.AppID = OR2.AppID AND OR2.AppStatus = 'Approved' AND OR2.[Order] = OR1.[Order] + 1
WHERE OR1.AppStatus = 'In Review'
GROUP BY OR1.BidID
)
SELECT AVG(AveragePerBid) AS AveragePerTable
FROM BidAverage
AveragePerTable
---------------------------------------
1.250000
这里我试着解释一下重要的步骤:
每个 BidID、AppID、StatusTime 的记录数量 - 这只是根据状态出现的时间对记录进行编号(排序),并且每个(BidID、AppID)对重新开始编号。
;WITH OrderedRecords(BidID, AppID, AppStatus, StatusTime, [Order])
AS (
SELECT BidID
,AppID
,AppStatus
,StatusTime
, [Order] = ROW_NUMBER() OVER(PARTITION BY BidID, AppID ORDER BY StatusTime)
FROM @table
)
SELECT * FROM OrderedRecords
BidID AppID AppStatus StatusTime Order
----------- ----------- -------------------- --------------------------- --------------------
1 1 In Review 2019-01-02 12:00:00.0000000 1
1 1 Approved 2019-01-02 13:00:00.0000000 2
1 1 Approved 2019-01-02 13:30:00.0000000 3
1 2 In Review 2019-01-04 13:00:00.0000000 1
1 2 Approved 2019-01-04 15:00:00.0000000 2
2 2 Approved 2019-01-07 14:30:00.0000000 1
2 2 In Review 2019-01-07 15:00:00.0000000 2
2 2 Approved 2019-01-07 16:00:00.0000000 3
3 1 In Review 2019-01-09 13:00:00.0000000 1
4 1 Approved 2019-01-09 13:00:00.0000000 1
选择正确的 'In Review'、'Approved' 对记录
基本上 CTE BidAverage select 的内部 select 来自 'OrderedRecords' CTE 的所有 'InReview' 记录,并通过加入相同的 table 试图找到'Approved' 记录具有相同的 BidID、AppID 和比 'InReview' 订单高 1 的订单(这是获得相邻 'In reviw' 和 'Approved' 的技巧。INNER 连接切断 'In review' 没有 'Approved' 的记录,反之亦然。
;WITH OrderedRecords(BidID, AppID, AppStatus, StatusTime, [Order])
AS (
SELECT BidID
,AppID
,AppStatus
,StatusTime
, [Order] = ROW_NUMBER() OVER(PARTITION BY BidID, AppID ORDER BY StatusTime)
FROM @table
)
SELECT OR1.BidID, OR1.AppID, OR1.AppStatus, OR1.StatusTime, OR1.[Order], OR2.AppStatus, OR2.StatusTime, OR2.[Order]
FROM OrderedRecords OR1
INNER JOIN OrderedRecords OR2
ON OR1.BidID = OR2.BidID AND OR1.AppID = OR2.AppID AND OR2.AppStatus = 'Approved' AND OR2.[Order] = OR1.[Order] + 1
WHERE OR1.AppStatus = 'In Review'
BidID AppID AppStatus StatusTime Order AppStatus StatusTime Order
----------- ----------- -------------------- --------------------------- -------------------- -------------------- --------------------------- --------------------
1 1 In Review 2019-01-02 12:00:00.0000000 1 Approved 2019-01-02 13:00:00.0000000 2
1 2 In Review 2019-01-04 13:00:00.0000000 1 Approved 2019-01-04 15:00:00.0000000 2
2 2 In Review 2019-01-07 15:00:00.0000000 2 Approved 2019-01-07 16:00:00.0000000 3
当你把所有这些放在一起时(这个答案顶部的最终脚本),你就得到了你需要的。正如我上面所说,这里的限制是每个 BidID 和 AppID 只有一个 'In Review' 记录。 (但可以出现多个 'Approved' 并且 'In review' 不需要是第一个按时间)
我有以下 table 格式
ID Status Date
16 In Review 2017-07-03 08:23:11.000
16 Approved 2017-07-03 08:23:20.000
16 Approved 2017-07-11 10:34:27.000
我正在尝试获取审查中和批准之间的时间差,应该是 9 秒..
这是我之前
这是它的代码
select avg(avg_bid_diff)
from (select bid, avg(diff*1.0) as avg_bid_diff
from (select bid, appid,
datediff(second, min(starttime), max(statustime)) as diff
from t
where appstatus in ('In Review', 'Approved')
group by bid, appid
having count(*) = 2
) ba
group by bid
) b;
问题是,当它考虑最小值和最大值时,我得到第一行和第三行之间的时间差,当只有 2 个状态时,但我需要的是第一次审查和下一次审查之间的时间差批准
谁能告诉我应该如何更改查询以获得下一个批准的时差。
谢谢
这有点棘手,但目前看来效果不错。唯一的限制是对于每个唯一的(BidID,AppID)对,没有或只有一个状态为 'In Review'.
的记录我对链式 CTE 使用了完全不同的方法:
DECLARE @table TABLE
(
BidID int,
AppID int,
AppStatus nvarchar(20),
StatusTime DATETIME2
);
INSERT INTO @table (BidID, AppID, AppStatus, StatusTime)
VALUES
(1, 1, 'In Review', '2019-01-02 12:00:00'),
(1, 1, 'Approved', '2019-01-02 13:00:00'),
(1, 1, 'Approved', '2019-01-02 13:30:00'),
(1, 2, 'In Review', '2019-01-04 13:00:00'),
(1, 2, 'Approved', '2019-01-04 15:00:00'),
(2, 2, 'Approved', '2019-01-07 14:30:00'),
(2, 2, 'In Review', '2019-01-07 15:00:00'),
(2, 2, 'Approved', '2019-01-07 16:00:00'),
(3, 1, 'In Review', '2019-01-09 13:00:00'),
(4, 1, 'Approved', '2019-01-09 13:00:00');
;WITH OrderedRecords(BidID, AppID, AppStatus, StatusTime, [Order])
AS (
SELECT BidID
,AppID
,AppStatus
,StatusTime
, [Order] = ROW_NUMBER() OVER(PARTITION BY BidID, AppID ORDER BY StatusTime)
FROM @table
),
BidAverage(BidID, AveragePerBid)
AS (
SELECT OR1.BidID, AVG(CAST(DATEDIFF(HOUR, OR1.StatusTime, OR2.StatusTime) AS DECIMAL)) AS AveragePerBid
FROM OrderedRecords OR1
INNER JOIN OrderedRecords OR2
ON OR1.BidID = OR2.BidID AND OR1.AppID = OR2.AppID AND OR2.AppStatus = 'Approved' AND OR2.[Order] = OR1.[Order] + 1
WHERE OR1.AppStatus = 'In Review'
GROUP BY OR1.BidID
)
SELECT AVG(AveragePerBid) AS AveragePerTable
FROM BidAverage
AveragePerTable
---------------------------------------
1.250000
这里我试着解释一下重要的步骤:
每个 BidID、AppID、StatusTime 的记录数量 - 这只是根据状态出现的时间对记录进行编号(排序),并且每个(BidID、AppID)对重新开始编号。
;WITH OrderedRecords(BidID, AppID, AppStatus, StatusTime, [Order]) AS ( SELECT BidID ,AppID ,AppStatus ,StatusTime , [Order] = ROW_NUMBER() OVER(PARTITION BY BidID, AppID ORDER BY StatusTime) FROM @table ) SELECT * FROM OrderedRecords BidID AppID AppStatus StatusTime Order ----------- ----------- -------------------- --------------------------- -------------------- 1 1 In Review 2019-01-02 12:00:00.0000000 1 1 1 Approved 2019-01-02 13:00:00.0000000 2 1 1 Approved 2019-01-02 13:30:00.0000000 3 1 2 In Review 2019-01-04 13:00:00.0000000 1 1 2 Approved 2019-01-04 15:00:00.0000000 2 2 2 Approved 2019-01-07 14:30:00.0000000 1 2 2 In Review 2019-01-07 15:00:00.0000000 2 2 2 Approved 2019-01-07 16:00:00.0000000 3 3 1 In Review 2019-01-09 13:00:00.0000000 1 4 1 Approved 2019-01-09 13:00:00.0000000 1
选择正确的 'In Review'、'Approved' 对记录
基本上 CTE BidAverage select 的内部 select 来自 'OrderedRecords' CTE 的所有 'InReview' 记录,并通过加入相同的 table 试图找到'Approved' 记录具有相同的 BidID、AppID 和比 'InReview' 订单高 1 的订单(这是获得相邻 'In reviw' 和 'Approved' 的技巧。INNER 连接切断 'In review' 没有 'Approved' 的记录,反之亦然。
;WITH OrderedRecords(BidID, AppID, AppStatus, StatusTime, [Order])
AS (
SELECT BidID
,AppID
,AppStatus
,StatusTime
, [Order] = ROW_NUMBER() OVER(PARTITION BY BidID, AppID ORDER BY StatusTime)
FROM @table
)
SELECT OR1.BidID, OR1.AppID, OR1.AppStatus, OR1.StatusTime, OR1.[Order], OR2.AppStatus, OR2.StatusTime, OR2.[Order]
FROM OrderedRecords OR1
INNER JOIN OrderedRecords OR2
ON OR1.BidID = OR2.BidID AND OR1.AppID = OR2.AppID AND OR2.AppStatus = 'Approved' AND OR2.[Order] = OR1.[Order] + 1
WHERE OR1.AppStatus = 'In Review'
BidID AppID AppStatus StatusTime Order AppStatus StatusTime Order
----------- ----------- -------------------- --------------------------- -------------------- -------------------- --------------------------- --------------------
1 1 In Review 2019-01-02 12:00:00.0000000 1 Approved 2019-01-02 13:00:00.0000000 2
1 2 In Review 2019-01-04 13:00:00.0000000 1 Approved 2019-01-04 15:00:00.0000000 2
2 2 In Review 2019-01-07 15:00:00.0000000 2 Approved 2019-01-07 16:00:00.0000000 3
当你把所有这些放在一起时(这个答案顶部的最终脚本),你就得到了你需要的。正如我上面所说,这里的限制是每个 BidID 和 AppID 只有一个 'In Review' 记录。 (但可以出现多个 'Approved' 并且 'In review' 不需要是第一个按时间)