2013-12-05 2 views
0

Еще один вопрос «последовательных вхождений» MySQL, но я думаю, что его раньше не спрашивали.MySQL-запрос для подсчета последовательных вхождений определенных чисел

У меня есть таблица, которая выглядит следующим

+----+------+---------------------+------+-----------+--------------+ 
| id | unit |  datetime  | idle | idlecount | boutduration | 
+----+------+---------------------+------+-----------+--------------+ 
| 1 | A | 2009-12-04 08:10:05 | 139 |   |    | 
| 2 | A | 2009-12-04 08:20:05 | 107 |   |    | 
| 3 | A | 2009-12-04 08:30:05 | 0 |   |    | 
| 4 | A | 2009-12-04 08:40:05 | 144 |   |    | 
| 5 | A | 2009-12-04 08:50:05 | 0 |   |    | 
| 6 | A | 2009-12-04 09:00:05 | 0 |   |    | 
| 7 | A | 2009-12-04 09:10:05 | 58 |   |    | 
| 8 | A | 2009-12-04 09:20:05 | 0 |   |    | 
| 9 | A | 2009-12-04 09:30:05 | 0 |   |    | 
| 10 | A | 2009-12-04 09:40:05 | 0 |   |    | 
| 11 | A | 2009-12-04 09:50:05 | 0 |   |    | 
| 12 | A | 2009-12-04 10:00:05 | 107 |   |    | 
| 13 | A | 2009-12-04 10:10:05 | 0 |   |    | 
| 14 | A | 2009-12-04 10:20:05 | 144 |   |    | 
| etc... 

Мне нужно подсчитать число последовательных появлений нулей в колонке idle и определить продолжительность каждой последовательности. Отдельные случаи не имеют значения. Таким образом, результат должен выглядеть следующим образом

+----+------+---------------------+------+-----------+--------------+ 
| id | unit |  datetime  | idle | idlecount | boutduration | 
+----+------+---------------------+------+-----------+--------------+ 
| 1 | A | 2009-12-04 08:10:05 | 139 |   |    | 
| 2 | A | 2009-12-04 08:20:05 | 107 |   |    | 
| 3 | A | 2009-12-04 08:30:05 | 0 |   |    | 
| 4 | A | 2009-12-04 08:40:05 | 144 |   |    | 
| 5 | A | 2009-12-04 08:50:05 | 0 |  2  | 00:20:00 | 
| 6 | A | 2009-12-04 09:00:05 | 0 |   |    | 
| 7 | A | 2009-12-04 09:10:05 | 58 |   |    | 
| 8 | A | 2009-12-04 09:20:05 | 0 |  4  | 00:40:00 | 
| 9 | A | 2009-12-04 09:30:05 | 0 |   |    | 
| 10 | A | 2009-12-04 09:40:05 | 0 |   |    | 
| 11 | A | 2009-12-04 09:50:05 | 0 |   |    | 
| 12 | A | 2009-12-04 10:00:05 | 107 |   |    | 
| 13 | A | 2009-12-04 10:10:05 | 0 |   |    | 
| 14 | A | 2009-12-04 10:20:05 | 144 |   |    | 
| etc... 

Я предполагаю, что это требует использования flow control statements, но я никогда не использовал это раньше, и чувствовать себя немного запуганы документации MySQL. Тем не менее я мечтаю об одном запросе-решении.

Cheers, Том

ответ

0

Вы можете сделать это с помощью коррелированных подзапросов. Первое получает следующее ненулевое значение после каждого. Второй подсчитывает значения между ними. Вот пример, чтобы получить кол-во простоя:

select t.*, 
     (select (case when count(*) > 1 then count(*) end) 
     from t t3 
     where t3.id >= t.id and 
       (t3.id < t.nextNonZeroIdle or nextNonZeroIdle is NULL) and 
       t3.idle = 0 
     ) as IdleCOunt 
from (select t.id, t.unit, t.datetime, t.idle, 
      (select id 
       from t t2 
       where t2.unit = t.unit and 
        t2.id > t.id and 
        t2.idle > 0 
       order by id 
       limit 1 
      ) as nextNonZeroIdle 
     from t 
    ) t 
from t; 
+0

Вау, я все еще перевариваю ваш ответ. Но у меня есть догадка, что этот запрос может занять несколько часов, чтобы перебрать мою таблицу. У него около 1,7 миллиона строк ...;) – Tomm

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