2015-09-11 78 views
2

我有一張表,每秒有一個車輛的速度記錄。如果車輛停止speed列的值爲0.我需要計算車輛的運動時間。計數記錄執行超過'N'Consecutinve值

條件:

  1. 如果車輛停止3秒以上,這將被視爲STOPPEDTIME
  2. 如果車輛停止時間少於3秒,這將被視爲MOVEMENTTIME

我已經有一個遊標來計算這個值,但我想刪除遊標的使用並優化查詢。

樣本數據:

create table Vehicle(Timer datetime,Speed int) 
insert into Vehicle values ('1-Jan-2015 00:00:01',10) 
insert into Vehicle values ('1-Jan-2015 00:00:02',14) 
insert into Vehicle values ('1-Jan-2015 00:00:03',15) 
insert into Vehicle values ('1-Jan-2015 00:00:04',14) 
insert into Vehicle values ('1-Jan-2015 00:00:05',16) 
insert into Vehicle values ('1-Jan-2015 00:00:06',0) -- do not count (3 consecutive) 
insert into Vehicle values ('1-Jan-2015 00:00:07',0) -- do not count (3 consecutive) 
insert into Vehicle values ('1-Jan-2015 00:00:08',0) -- do not count (3 consecutive) 
insert into Vehicle values ('1-Jan-2015 00:00:09',4) 
insert into Vehicle values ('1-Jan-2015 00:00:10',5) 
insert into Vehicle values ('1-Jan-2015 00:00:11',5) 
insert into Vehicle values ('1-Jan-2015 00:00:12',0) 
insert into Vehicle values ('1-Jan-2015 00:00:13',0) 
insert into Vehicle values ('1-Jan-2015 00:00:14',14) 
insert into Vehicle values ('1-Jan-2015 00:00:15',15) 
insert into Vehicle values ('1-Jan-2015 00:00:16',0)-- do not count (4 consecutive) 
insert into Vehicle values ('1-Jan-2015 00:00:17',0)-- do not count (4 consecutive) 
insert into Vehicle values ('1-Jan-2015 00:00:18',0)-- do not count (4 consecutive) 
insert into Vehicle values ('1-Jan-2015 00:00:19',0)-- do not count (4 consecutive) 
insert into Vehicle values ('1-Jan-2015 00:00:20',10) 
insert into Vehicle values ('1-Jan-2015 00:00:21',12) 

-- select * from Vehicle 

結果

MOVEMENTTIME (in Seconds) 
-------------------- 
14 

回答

4

使用ROW_NUMBER

SQL Fiddle

;WITH Cte AS(
    SELECT *, 
     RN = ROW_NUMBER() OVER(ORDER BY Timer) - 
      ROW_NUMBER() OVER(
       PARTITION BY CASE WHEN Speed > 0 THEN 1 ELSE 0 END 
       ORDER BY Timer 
      ) 
    FROM Vehicle 
), 
CteCnt AS(
    SELECT RN,Speed, cnt = COUNT(*) 
    FROM Cte 
    GROUP BY RN, Speed 
) 
SELECT SUM(cnt) 
FROM CteCnt 
WHERE 
    Speed > 0 
    OR (Speed = 0 AND cnt < 3)