2015-12-24 3 views
1

Мне нужно написать T-SQL, чтобы перебирать строки скорости как (Max/Min/Avg), но при условии, что если какая-либо строка < speedvalue, тогда (Max/Min/ср) будет шоу для нового над рядами скоростиГруппа SQL Server по значению! = Предыдущее значение без цикла курсора

Например это моя таблица базы данных и иметь флаг, если эта строка является превышение скорости или не

rownum Time    overspeed overspeedrowid 
1 2015-12-06 06:18:46.283 0   0 
2 2015-12-06 06:19:46.283 1   0 
3 2015-12-06 06:20:46.283 1   0 
4 2015-12-06 06:21:46.283 0   0 
5 2015-12-06 06:22:46.283 0   0 
6 2015-12-06 06:23:46.283 1   0 
7 2015-12-06 06:24:46.283 1   0 
8 2015-12-06 06:25:46.283 1   0 
9 2015-12-06 06:26:46.283 1   0 
10 2015-12-06 06:27:46.283 0   0 
11 2015-12-06 06:28:46.283 0   0 
12 2015-12-06 06:29:46.283 0   0 
13 2015-12-06 06:30:46.283 1   0 
14 2015-12-06 06:31:46.283 1   0 
15 2015-12-06 06:32:46.283 1   0 
16 2015-12-06 06:33:46.283 0   0 
17 2015-12-06 06:34:46.283 0   0 
18 2015-12-06 06:35:46.283 1   0 
19 2015-12-06 06:36:46.283 0   0 
20 2015-12-06 06:37:46.283 0   0 
21 2015-12-06 06:38:46.283 0   0 
22 2015-12-06 06:39:46.283 1   0 
23 2015-12-06 06:40:46.283 1   0 

Мой план заключается в использовании следующей

  1. Петля по строкам, и если ток! = пред и пред = 0, то новое overspeedrowid значение
  2. Если ток = пред и пред = 1, то ток overspeedrowid = предыдущая overspeedrowid
  3. Выберите из расчетной таблицы мин/макс группа по overspeedrowid

так расчетная таблица должна быть такой

rownum Time    overspeed overspeedrowid 
1 2015-12-06 06:18:46.283 0   0 
2 2015-12-06 06:19:46.283 1   1 
3 2015-12-06 06:20:46.283 1   1 
4 2015-12-06 06:21:46.283 0   0 
5 2015-12-06 06:22:46.283 0   0 
6 2015-12-06 06:23:46.283 1   2 
7 2015-12-06 06:24:46.283 1   2 
8 2015-12-06 06:25:46.283 1   2 
9 2015-12-06 06:26:46.283 1   2 
10 2015-12-06 06:27:46.283 0   0 
11 2015-12-06 06:28:46.283 0   0 
12 2015-12-06 06:29:46.283 0   0 
13 2015-12-06 06:30:46.283 1   3 
14 2015-12-06 06:31:46.283 1   3 
15 2015-12-06 06:32:46.283 1   3 
16 2015-12-06 06:33:46.283 0   0 
17 2015-12-06 06:34:46.283 0   0 
18 2015-12-06 06:35:46.283 1   4 
19 2015-12-06 06:36:46.283 0   0 
20 2015-12-06 06:37:46.283 0   0 
21 2015-12-06 06:38:46.283 0   0 
22 2015-12-06 06:39:46.283 1   5 
23 2015-12-06 06:40:46.283 1   5 
  • Я попробовал курсор, но это занимает много времени, так как данные производства составляет около 2000000 строк.

  • Я попытался Update с присоединиться к строкам 1 и сравнить построчно 1 с током его быстро не исправить, как это обновление только второй ряд

Вот что я сделал, но его обновление только второй ряд,

update #temp1 
set #temp1.overspeedrowid = @a, @a = @a + 1 
from #temp1 
left join #temp1 prev on prev.rownum = #temp1.rownum - 1 
where 
    (#temp1.overspeed != prev.overspeed and #temp1.overspeed = 1) 

update #temp1 
set #temp1.overspeedrowid = prev. overspeedrowid 
from #temp1 
left join #temp1 prev on prev.rownum = #temp1.rownum - 1 
where 
    (#temp1.overspeed = prev.overspeed and #temp1.overspeed = 1) 
+2

Совет. Как показано в ответе Гордона Линоффа, полезно отметить вопросы базы данных как с помощью соответствующего программного обеспечения (MySQL, Oracle, DB2, ...) и версии, например. 'SQL-сервер-2014'. Различия в синтаксисе и особенностях часто влияют на ответы. – HABO

ответ

2

В SQL Server 2012+, вы можете использовать lag() с последующим "состояние" нарастающего итога:

select t.*, 
     (case when overspeed = 0 then 0 
      else sum(OverSpeedFlag) over (order by time) 
     end) as overspeedrowid 
from (select t.*, 
      (case when lag(overspeed) over (order by time) = 0 and overspeed = 1 
        then 1 else 0 
       end) as OverSpeedFlag 
     from #temp1 t 
    ) t; 
+0

Отлично, его работа, спасибо за функцию lag() –

Смежные вопросы