我有一个工作流应用程序,当状态发生变化时,工作流将写入数据库,如下所示。没有结束时间,因为它是一系列事件。我想创建一个将按WorkFlowID分组的查询,并总计在每个查询中花费的时间。我不确定如何开始
我的表和数据看起来像这样
+------------+---------------------+ | WorkFlowID | EventTime | +------------+---------------------+ | 1 | 07/15/2015 12:00 AM | | 2 | 07/15/2015 12:10 AM | | 3 | 07/15/2015 12:20 AM | | 2 | 07/15/2015 12:30 AM | | 3 | 07/15/2015 12:40 AM | | 4 | 07/15/2015 12:50 AM | +------------+---------------------+
我的最终结果应该是:
+------------+-----------------+ | WorkFlowID | TotalTimeInMins | +------------+-----------------+ | 1 | 10 | | 2 | 20 | | 3 | 20 | | 4 | 10 | +------------+-----------------+
答案 0 :(得分:1)
在SQL Server 2012+中,您只需使用lead()
。在SQL Server 2008中有几种方法可以解决这个问题。这里有一个使用`outer apply:
select t.WorkFlowId,
sum(datediff(second, EventTime, nextTime)) / 60.0 as NumMinutes
from (select t.*, t2.EventTime as nextTime
from table t outer apply
(select top 1 t2.*
from table t2
where t2.EventTime > t.EventTime
order by t2.EventTime
) t2
) tt
group by t.WorkFlowId;
唯一的问题是如何为事件4获得“10”。没有以下事件,因此该值没有意义。您可以使用datediff(second, EventTime coalesce(NextEvent, getdate())
来处理NULL
值。
答案 1 :(得分:0)
作为替代方案:
;WITH t AS (
SELECT *,
ROW_NUMBER() OVER (ORDER BY EventTime) As rn
FROM
yourTable)
SELECT
t1.WorkFlowID,
SUM(DATEDIFF(SECOND, t1.EventTime, ISNULL(t2.EventTime, GETDATE()) / 60) As TotalTimeInMins
FROM t t1
LEFT JOIN t t2
ON t1.rn = t2.rn - 1
答案 2 :(得分:0)
一个适用于所有方法(好吧,我不了解SQL 6.5)版本的方法的基础是使用group by
子句:
SELECT
WorkFlowID
,datediff(mi, min(EventTime), max(EventTime)) TotalTimeInMins
from MyTable
group by WorkFlowID
这确实留下了如何在开始时间和(可能)没有结束时间的情况下获得10分钟的问题。如上所述,此查询将列出 具有TotalTimeInMins = 0的WorkFlowID,看起来足够准确。以下变体将删除所有"仅启动"项目:
SELECT
WorkFlowID
,datediff(mi, min(EventTime), max(EventTime)) TotalTimeInMins
from MyTable
group by WorkFlowID
having count(*) > 1
(快速解释:having
为group by
,where
为from
)