我正在研究一个工作项目,数据记录类型系统。目前使用SQL Server 2008,可以根据需要进行升级。目前我们每隔1分钟设备一次,我们正在收集各种信息,我只担心时间和步数。
我正在尝试确定时间的长短,机器在搬出前花费了一定的时间。我有一种方法,我正在使用它目前的工作原理。然而,运行需要很长时间。 (5小时以上)
我目前设置的视图看起来像这样。
With Steps AS (SELECT *, ROW_NUMBER() OVER (ORDER BY Time) AS RowNum
FROM dbo.Data_All)
SELECT Steps.Time, Steps.[Production Step]
FROM Steps INNER JOIN
Steps AS Y ON Steps.RowNum = y.RowNum + 1 AND
Steps.[Production Step] <> y.[Production Step]
这样做会给我一个细分,随着时间进入该步骤。这将需要大约30秒才能运行,所以并不坏。意识到我们拥有超过250,000条记录,并且每天都在增长。
| Time | Step # |
-----------------------------
| 7-25-2014 14:32 | 11 |
| 7-25-2014 15:32 | 13 |
| 7-25-2014 15:40 | 14 |
| 7-25-2014 15:42 | 15 |
| 7-25-2014 15:50 | 8 |
然后我根据该视图运行查询,以获取我,步骤,时间,下一步时间和持续时间。这是查询是什么需要很长时间。所以我正在寻找一种更快地完成这项工作的方法。
With CTE AS (select Time, Row_Numbers=ROW_NUMBER() Over (Order by Time),
[production step] from Time_In_Step)
Select [Current Row].[Production Step], [current row].Time,
[next row].Time AS [Next Step Time], Datediff(mi, [current row].Time,
[Next row].time) AS [Duration in Min]
FROM CTE [Current Row]
LEFT JOIN CTE [Next Row] ON
[Next Row].Row_Numbers = [Current Row].Row_Numbers + 1
这样做我得到以下内容,这就是我想要的。只是一种更快的方法。
| Time | Step # | Next Step Time | Duration in Min |
-----------------------------------------------------------------
| 7-25-2014 14:32 | 11 | 7-25-2014 15:32 | 60 |
| 7-25-2014 15:32 | 13 | 7-25-2014 15:40 | 8 |
| 7-25-2014 15:40 | 14 | 7-25-2014 15:42 | 2 |
| 7-25-2014 15:42 | 15 | 7-25-2014 15:50 | 8 |
| 7-25-2014 15:50 | 8 | Etc..... | DateDiff
有关如何优化此功能的任何想法?如果您对我正在尝试做的事情有任何更多的想法,请告诉我。
答案 0 :(得分:1)
我建议使用cross apply
:
select c.[Production Step], c.Time,
n.Time AS [n Step Time],
Datediff(mi, c.Time, n.time) AS [Duration in Min]
from time_in_step c cross apply
(select top 1 n.*
from time_in_step n
where c.time < n.time
) n;
time
上的索引有助于提升效果。
答案 1 :(得分:0)
您可以尝试以下方法:
select c.production_step,
c.time,
case when f.time = c.time then null else f.time end as next_step_time,
datediff(mi, c.time, f.time) as dur_in_mins
from time_in_step c
cross join time_in_step f
where f.time = (select min(x.time) from time_in_step x where x.time > c.time)
or (not exists (select 1 from time_in_step x where x.time > c.time)
and f.time = c.time)