确定一个阶段需要多长时间,查看当前行和下一行

时间:2014-07-27 20:07:33

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

我正在研究一个工作项目,数据记录类型系统。目前使用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        

有关如何优化此功能的任何想法?如果您对我正在尝试做的事情有任何更多的想法,请告诉我。

2 个答案:

答案 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)