|
我有下表,包括每15分钟从几个不同的设备中读取的值: u5 N, U M1 _; T* j5 E6 T& \
ID DeviceID Date Value----------------------------------------------1 3 244 .08.2011年00:000 .512 3 2444 24444.08.2011年15:00.333 3 .08.2011年00:30:00 04 244.08.2011年 00:45:00 .155 3 2444 .08.2011年1:00:000 1.056 3 .08.2011年3:15:00 3.8我想在表中找到所有设备的所有差距,每的所有设备的所有差距。对于上表,结果应该是这样的:$ V: `1 z! B) Z/ D/ S9 `! j; `
DeviceID StartDate EndDate-------------------------------------------------------3 2444.08.2011年1:000 244.08.2011 03:15:00大约有3.5万台设备和1亿个项目。) X. ]* O; I3 O4 H* p& Y
这是我试过的;它很慢,但回到我需要的地方。然而,除了速度之外,还有另一个问题:它只能在给定月份设备的最后一个项目之前找到丢失的时间间隔;之后的所有内容都将被忽略,因此可能会错过额外的缺失间隔。
" J" I5 H0 ], Z- E& g3 g4 d8 GSELECT t2.Date AS StartDate ,t1.Date AS EndDateFROM TestTable t1 INNER JOIN TestTable t2 ON t1.DeviceID = t2.DeviceIDWHERE (t2.Date = (SELECT MAX(Date) FROM TestTable t3 WHERE t3.Date 15) AND t1.DeviceID = @id AND DATEPART(YEAR,t1.Date) = @year AND DATEPART(MONTH,t1.Date) = @month
6 i D) e0 r* u& G 解决方案:
4 U, c6 ]0 J9 {1 g% U( H3 A: a 跟随应该起作用,而不仅仅是一个deviceid的单个记录。
( e0 d# {1 ?* L; g9 u [7 |8 D2 J其要旨是
% j# _& S9 G% `7 W) V2 N( Q将行号添加到每个记录中,按顺序排列,Date然后重新启动每个记录DeviceID。
% o e( b7 h4 O2 Z. r: w* Q, P+ w$ z' k与self联接以创建包含两个原始行的组合的行的结果。每行的列之间的关系是行号( 1)和DeviceID。
6 O, Q$ E7 V5 c ^仅保留相关Date时间超过15分钟的线。SQL语句
w4 P- y/ n; Z* v* U/ K3 B$ @;WITH t AS ( SELECT *,rn = ROW_NUMBER() OVER (PARTITION BY DeviceID ORDER BY Date) FROM TestTable) SELECT t1.DeviceID,t1.Date,t2.DateFROM t t INNER JOIN t t2 ON t2.DeviceID = t1.DeviceID AND t2.rn = t1.rn 1WHERE DATEDIFF(MINUTE,t1.Date,t2.Date) > 15测试脚本
' h* m* d8 Y! O, S* T- x;WITH TestTable (ID,DeviceID,Date,Value) AS ( SELECT 1,3,'2011-08-24 00:00:00',0.51 UNION ALL SELECT 2,3,'2011-08-24 00:15:00',2.9 UNION ALL SELECT 3,3,'2011-08-0 UNION ALL SELECT 4,3,'2011-08-24 00:45:00',7.1 UNION ALL SELECT 5,3,'2011-08-24 01:00:00',1.05 UNION ALL SELECT 6,3,'2011-08-24 03:15:00',3.8 ),t AS ( SELECT *,rn = ROW_NUMBER() OVER (PARTITION BY DeviceID ORDER BY Date) FROM TestTable) SELECT t1.DeviceID,t1.Date,t2.DateFROM t t INNER JOIN t t2 ON t2.DeviceID = t1.DeviceID AND t2.rn = t1.rn 1WHERE DATEDIFF(MINUTE,t1.Date,t2.Date) > |
|