Tsql 计算上一行之间的持续时间

Tsql 计算上一行之间的持续时间,tsql,sql-server-2012,Tsql,Sql Server 2012,我有一个SQL Server 2012表,其中包含以下数据: Id; InstanceNo; ActionDate; Text ----------------------------------------------- 1; 27500; 2016-04-15 13:39:11.843; Start 2; 27500; 2016-04-15 13:40:12.857; Step1 3; 27500; 2016-04-15 13:4

我有一个SQL Server 2012表,其中包含以下数据:

Id; InstanceNo; ActionDate;              Text
-----------------------------------------------
1;  27500;      2016-04-15 13:39:11.843; Start
2;  27500;      2016-04-15 13:40:12.857; Step1
3;  27500;      2016-04-15 13:41:13.856; Step2
4;  27500;      2016-04-15 13:43:17.657; Step3
5;  27500;      2016-04-15 13:45:18.257; End
6;  29321;      2016-04-14 12:32:12.857; Start
7;  29321;      2016-04-14 12:40:17.247; Step1
8;  29321;      2016-04-15 09:18:19.156; End
Id是标识,表按InstanceNo、ActionDate排序

我想计算每条线之间的持续时间

问题是,每次出现一个新实例No时,开始值应该是“0”,而不是示例中Id 5和Id 6之间的持续时间

实际上,我正在使用这个查询。表中只有25000行的速度很慢,当它是一个新实例时,不是从零开始的:

SELECT 
    t1.ID, t1.InstanceNo, t1.ActionDate, t1.Text, 
    DATEDIFF(ss, x.ActionDate, t1.ActionDate) AS [Duration sec]
FROM 
    Tmp_Stat_Sepa t1
OUTER APPLY 
    (SELECT TOP 1 ActionDate 
     FROM Tmp_Stat_Sepa t2 
     WHERE t2.ID < t1.ID 
     ORDER BY t2.ID DESC) x

你没有提到你想要什么单位的差异,所以我用了秒

CREATE TABLE #Test (
  Id INTEGER,
  InstanceNo INTEGER,
  ActionDate DATETIME,
  Text VARCHAR(10)
);

INSERT INTO #Test (Id, InstanceNo, ActionDate, Text) VALUES
  (1,  27500,      '2016-04-15 13:39:11.843', 'Start'),
  (2,  27500,      '2016-04-15 13:40:12.857', 'Step1'),
  (3,  27500,      '2016-04-15 13:41:13.856', 'Step2'),
  (4,  27500,      '2016-04-15 13:43:17.657', 'Step3'),
  (5,  27500,      '2016-04-15 13:45:18.257', 'End'),
  (6,  29321,      '2016-04-14 12:32:12.857', 'Start'),
  (7,  29321,      '2016-04-14 12:40:17.247', 'Step1'),
  (8,  29321,      '2016-04-15 09:18:19.156', 'End');


SELECT A.Id
      ,A.InstanceNo
      ,A.ActionDate
      ,A.Text
      ,COALESCE(DATEDIFF(SECOND, LastActionDate, ActionDate), 0) DiffInSeconds
FROM (
SELECT Id
      ,InstanceNo
      ,ActionDate
      ,Text
      ,LAG(ActionDate) OVER (PARTITION BY InstanceNo ORDER BY InstanceNo, ActionDate) LastActionDate 
      FROM #Test ) A


Id          InstanceNo  ActionDate              Text       DiffInSeconds
----------- ----------- ----------------------- ---------- -------------
1           27500       2016-04-15 13:39:11.843 Start      0
2           27500       2016-04-15 13:40:12.857 Step1      61
3           27500       2016-04-15 13:41:13.857 Step2      61
4           27500       2016-04-15 13:43:17.657 Step3      124
5           27500       2016-04-15 13:45:18.257 End        121
6           29321       2016-04-14 12:32:12.857 Start      0
7           29321       2016-04-14 12:40:17.247 Step1      485
8           29321       2016-04-15 09:18:19.157 End        74282

(8 row(s) affected)

你试过滞后函数吗?我不知道滞后函数。我用这个查询得到了最快的结果,但没有按我想要的那样工作:选择t1.*,DATEDIFFss,t2.ActionDate,t1.ActionDate Duration FROM Tmp_Stat_Sepa t1 join Tmp_Stat_Sepa t2 on t2.ID=t1.ID-1表是按顺序排列的-不,表不是按顺序排列的-只有我们的输出可以排序,如果在查询中包含ORDER BY,则行是表中注入期间的ORDER BY。抱歉误解了。@Chris,插入顺序与结果顺序无关。如果未指定order BY,则并行、分组、聚合运算符可以自由地以任何顺序返回结果。除非明确定义上一个/下一个关系,否则不存在上一个/下一个关系。使用OVER PARTITION BY InstanceNo ORDER BY ActionDate检查滞后函数,以获取同一实例中的先前步骤