我有一张桌子
TABLE [dbo].[IssueStatus](
[Id] [int] PRIMARY KEY ,
[IssueId] [varchar(50)],
[OldStatus] [int] ,
[NewStatus] [int] ,
[Updated] [datetime]
2个状态列可以有3个可能的值1,2和3(1表示打开,2表示正在进行,3表示已解决)。
Updated
包含状态更改时的日期时间。问题的状态最初自动设置为1。我想计算问题进行时的总时间(以秒为单位)。
注意: - 状态可能会直接从1变为3 状态可能会从1更改为2,然后再更改为1,依此类推,但最终状态将保证为3
我已经检查过了 - Calculate time duration between differents records in a table based on datetimes,但它对我没什么帮助
原始情况要复杂得多 1表示打开,3表示正在打开,4表示重新打开,5表示已解决,6表示已关闭
谢谢
79890 26327 3 In Progress 5 Resolved 2014-12-17 09:10:03.767
74980 26328 3 In Progress 5 Resolved 2014-11-20 10:21:29.780
74748 26328 1 Open 3 In Progress 2014-11-20 02:34:15.440
77843 26329 1 Open 3 In Progress 2014-12-08 08:04:04.567
77857 26329 1 Open 5 Resolved 2014-12-08 08:23:57.720
77856 26329 3 In Progress 1 Open 2014-12-08 08:23:46.067
75107 26330 1 Open 5 Resolved 2014-11-21 06:37:28.810
76441 26330 5 Resolved 6 Closed 2014-12-02 07:27:39.927
78638 26331 1 Open 3 In Progress 2014-12-10 07:47:41.347
78091 26331 3 In Progress 1 Open 2014-12-09 02:44:36.970
77858 26331 1 Open 3 In Progress 2014-12-08 08:28:08.597
78641 26331 3 In Progress 1 Open 2014-12-10 07:57:03.603
78642 26331 1 Open 5 Resolved 2014-12-10 07:57:11.483
74753 26332 1 Open 3 In Progress 2014-11-20 02:59:11.013
74763 26332 3 In Progress 5 Resolved 2014-11-20 03:04:01.127
76846 26333 1 Open 5 Resolved 2014-12-05 00:57:09.140
76849 26340 1 Open 5 Resolved 2014-12-05 01:52:05.957
87861 26341 5 Resolved 6 Closed 2015-02-02 04:18:25.230
85491 26341 1 Open 5 Resolved 2015-01-22 04:48:13.003
77321 26342 3 In Progress 1 Open 2014-12-08 00:56:26.233
75029 26342 1 Open 3 In Progress 2014-11-21 02:48:41.440
79030 26342 3 In Progress 5 Resolved 2014-12-11 21:43:23.657
76395 26342 1 Open 3 In Progress 2014-12-02 02:58:17.063
75197 26342 3 In Progress 1 Open 2014-11-24 02:06:38.490
78502 26342 1 Open 3 In Progress 2014-12-10 02:28:18.570
74933 26343 1 Open 5 Resolved 2014-11-20 08:08:44.423
74821 26344 1 Open 5 Resolved 2014-11-20 05:56:00.513
75295 26345 1 Open 5 Resolved 2014-11-25 02:06:07.260
答案 0 :(得分:1)
在这种情况下,sql窗口函数真的可以派上用场。 假设您使用sql server 2012或更高版本,则可以使用lead函数。
例如:此潜在客户用法会添加“下一个”记录的日期时间:
SELECT *, lead(updated,1,getdate()) over (partition by issueid order by updated) NextDate from issuestatus
在这种情况下,“下一步”是同一个问题代码(partition by
)和updated
的顺序(如果没有下一条记录,则使用默认的getdate())
由于您的行中有下一个日期,因此直到下一行的持续时间仅为nextdate - 已更新。 (您可以使用lag
执行相同操作以获取从oldstatus到newstatus的持续时间,但在此处选择了lead,因为它可以使用当前正在进行的项目的默认getdate())
铅可以直接用于计算持续时间:
SELECT IssueID, newstatus Status,
datediff(minute,updated, lead(updated,1,getdate()) over (partition by issueid order by updated)) DurationInMinutes
from issuestatus
从那里获得总数可以很容易地用正常的总和完成,得出最终结果:
select sum(DurationInMinutes) TotalDuration from
(
SELECT IssueID, newstatus Status,
datediff(minute,updated, lead(updated,1,getdate()) over (partition by issueid order by updated)) DurationInMinutes
from issuestatus
) d
where Status = 2 --only duration of status progress
请注意,where status=
无法添加到子查询中,否则lead
将查找状态也为2的下一条记录。
当然,您也可以group by IssueID
来获取每个issueid的持续时间。
答案 1 :(得分:0)
我的查询显示每个条目处于状态2的时间。
使用此示例数据:
Id IssueId OldStatus NewStatus Updated
1 aa NULL 1 2015-01-01 14:00:00
2 aa 1 2 2015-01-01 16:00:00
4 aa 2 3 2015-01-01 17:30:00
5 bb NULL 1 2015-02-13 11:30:00
6 bb 1 2 2015-02-13 12:56:00
7 bb 2 3 2015-02-13 14:20:00
8 cc NULL 1 2015-02-14 11:30:00
9 cc 1 2 2015-02-14 12:56:00
10 cc 2 1 2015-02-14 13:19:00
11 cc 1 2 2015-02-14 14:20:00
12 cc 2 3 2015-02-14 14:25:00
我可以使用此查询:
;with NewStatus2 as (
SELECT Id, IssueId, Updated, ROW_NUMBER() over (Order BY IssueId, id) PrevID FROM IssueStatus [is]
WHERE NewStatus = 2 )
, OldStatus2 as (
SELECT Id, IssueId, Updated, ROW_NUMBER() over (Order BY IssueId, id) PrevID FROM IssueStatus [is]
WHERE OldStatus = 2 )
SELECT ns.IssueId
, ns.Updated FromTime
, os.Updated ToTime
, DATEDIFF(minute , ns.Updated , os.Updated) as TimeSpan_Spent_In_Status_2
FROM NewStatus2 ns
INNER JOIN OldStatus2 os ON ns.IssueId = os.IssueId
AND ns.PrevID = os.PrevID
ORDER BY ns.Updated , os.Updated;
得到这个结果:
IssueId FromTime ToTime TimeSpan_Spent_In_Status_2
aa 2015-01-01 16:00:00 2015-01-01 17:30:00 90
bb 2015-02-13 12:56:00 2015-02-13 14:20:00 84
cc 2015-02-14 12:56:00 2015-02-14 13:19:00 23
cc 2015-02-14 14:20:00 2015-02-14 14:25:00 5
编辑由@vibhavSarraf提供的查询和示例数据匹配结构
答案 2 :(得分:0)
这将为您提供所需的输出:
SELECT IssueId, SUM(diff) +
DATEDIFF(s, MIN(diffs.minU), MAX(maxU)) duration
FROM (
SELECT i1.IssueId, (DATEDIFF(s, Updated, limits.maxU) * IIF(NewStatus=2,1,-1)) diff, minU, maxU
FROM IssueStatus i1 INNER JOIN (
SELECT i2.IssueId, MIN(UPDATED) minU, MAX(UPDATED) maxU
FROM IssueStatus i2
GROUP BY IssueId) limits ON
i1.IssueId = limits.IssueId
WHERE NewStatus < 3) diffs
GROUP BY IssueId
这里的想法是每行可以单独处理,计算从Updated
到问题结束(MAX(Updated)
)的时间。然后乘以正/负1,取决于状态(正为2,负为1)。如果你总结所有这些,你将得到总进度时间减去初始开放持续时间,所以我们将其添加回计算。不幸的是,查询在构造方面变得“复杂”,由3 SELECT
构建。我相信它可以简化(如果我稍后会有时间,我会再次讨论它)