对于这个问题,假设我有一个包含以下数据的表:
1)姓名 2)心情 3)DateTime
我可以插入如下记录:
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
我想获得与这些情绪变化相关的“持续时间”信息!
我的桌子上有成千上万的记录,而且我不能承担花费太多时间的过程。计算这个的最佳方法是什么?
感谢您的帮助!
重要编辑: 情绪记录分组到数据包中,我们无法确定已插入的记录是否有较小的日期! (见我记录旁边的上述评论)
答案 0 :(得分:3)
可能的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
似乎是一个非常糟糕的主意(“If you self join the CTE it will kill you”)。我在临时表中测试了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