Sql server 基于日期时间计算表中不同记录之间的持续时间

Sql server 基于日期时间计算表中不同记录之间的持续时间,sql-server,view,calculated-columns,Sql Server,View,Calculated Columns,对于这个问题,假设我有一个包含以下数据的表: 1名 2情绪 3日期时间 我可以插入如下记录: Andy Happy '11.06.2012 - 14.06.07' -- Inserted on 11.06.2012 @ 19:12.32 Arthur Angry '11.06.2012 - 15.06.57' -- Inserted on 11.06.2012 @ 17:12.32 Andy Sad '11.06.2012 - 14.34.05' -- Ins

对于这个问题,假设我有一个包含以下数据的表:

1名 2情绪 3日期时间

我可以插入如下记录:

Andy    Happy    '11.06.2012 - 14.06.07' -- Inserted on 11.06.2012 @ 19:12.32
Arthur  Angry    '11.06.2012 - 15.06.57' -- Inserted on 11.06.2012 @ 17:12.32
Andy    Sad      '11.06.2012 - 14.34.05' -- Inserted on 11.06.2012 @ 17:12.32
Arthur  Happy    '11.06.2012 - 13.34.05' -- Inserted on 11.06.2012 @ 14:12.32
我想获得与这些情绪变化相关的持续时间信息

我的表可以容纳数千条或上百条记录,我无法承受花费太多时间的过程。最好的计算方法是什么

插入后触发,填充持续时间列? 填充以前创建的持续时间列的存储过程? 计算列? 一个我已经尝试过的视图,它需要2秒以上的时间来显示,这是完全不可接受的 还有别的主意吗? 谢谢你的帮助

重要编辑:
情绪记录分组到数据包中,我们无法确定已经插入的记录是否有更小的日期!请参见“我的记录”旁边的上述注释,可能的SQL版本:

WITH CTE AS(
    SELECT ROW_NUMBER()OVER(PARTITION BY [Name] ORDER BY [Time])As RowNum
    , *
    FROM @table T
)
SELECT 
    DiffSec=DATEDIFF(s,[Time],(SELECT [Time] FROM CTE c2 WHERE c2.[Name]=CTE.[Name] AND c2.RowNum=CTE.RowNum+1))
    , [Name]
    , Mood
    , [Time]
FROM CTE 
ORDER BY [Name],[RowNum]
结果:

DiffSec Name    Mood    Time
1678    Andy    Happy   2012-06-11 14:06:07.000
NULL    Andy    Sad     2012-06-11 14:34:05.000
5228    Arthur  Angry   2012-06-11 14:06:57.000
NULL    Arthur  Happy   2012-06-11 15:34:05.000
您的测试数据:

declare @table table(name varchar(10),mood varchar(10),time datetime);
insert into @table values('Andy','Happy',convert(datetime,'11.06.2012 14:06:07',104));
insert into @table values('Arthur','Angry',convert(datetime,'11.06.2012 14:06:57',104));
insert into @table values('Andy','Sad',convert(datetime,'11.06.2012 14:34:05',104));
insert into @table values('Arthur','Happy',convert(datetime,'11.06.2012 15:34:05',104));
编辑自加入CTE似乎是一个非常糟糕的主意。我在一个临时表中用500000条记录测试了我的查询,并在30分钟后取消了查询

下面是一个更快的方法,对于所有使用带有注释模式的子查询的人来说,只需4秒:

SELECT T.*
    ,(SELECT DATEDIFF(s,MAX(T2.Time),T.Time)
      FROM dbo.Temp T2
      WHERE T2.HE_Id = T.HE_Id
          AND T2.Time < T.Time
    ) AS DiffSec
FROM dbo.Temp AS T
ORDER BY HE_Id ,DiffSec

使用pivot查询将数据放入同一行,然后将该查询用作子查询,这样您就可以进行计算了。可以将情绪开始时间和情绪结束时间作为单独的列吗?如果是,那么您可以使用TO_CHAR函数来查找差异。您还可以在视图上放置索引,尽管它们是一些很大的限制。不要使用触发器。为什么需要存储可在查询时派生的冗余数据?如果您真的认为需要存储它,为什么不在插入新行时添加增量呢?它所要做的就是为同一用户获取现有的MAX[datetime]。@Limey您如何构建一个更快地回答此查询的索引视图?使用Denali/SQL 2012,现在分区有超前和滞后。@AndyM:500k记录相对较少。你在桌子上吗?您是在存储用户名还是只存储推荐的外键?@AndyM:尝试在表上创建此索引或类似索引:在表[name]、[Time]上创建索引idxNameTime@AndyM:名字是什么?情绪场是什么?@AndyM:如果你自己加入CTE,它会杀了你;-编辑我的答案以提供另一种方法。