Опитайте това:http://www.sqlfiddle.com/#!2/e9372/ 1
Предимството да го направите от страна на DB е, че можете да използвате заявката не само на PHP, можете също да я използвате на Java, C#, Python и т.н. И това се прави бързо от страната на DB
изберете if(idle_state =1, concat('Idle ', idle_count), concat('NonIdle ', non_idle_count) ) като Period, startTime, endTime, durationfrom( select @idle_count :=@idle_count + if( idle_state =1,1,0) като idle_count, @non_idle_count :=@non_idle_count +if(idle_state =0,1,0) като non_idle_count, state_group, idle_state, min(timeStamp) като startTime, max(timeStamp) като endTime, timestampdiff (секунда, min(timeStamp), max(timeStamp)) като продължителност от ( select *, @idle_state :=if(rpm между 800 и 900, 1, 0) as idle_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) като state_group, @prev_state :=@idle_state от (tbl, (изберете @state_group :=0 като y) като vars) подреждане по tbl.timeStamp ) като x,(изберете @idle_count :=0 като y, @non_idle_count :=0 като z) като vars група по state_group, idle_state) като резюме
Изход:
<предварителен код>| ПЕРИОД | НАЧАЛЕН ЧАС | КРАЙНО ВРЕМЕ | ПРОДЪЛЖИТЕЛНОСТ ||-----------|----------------------------|------ ----------------------|----------|| Неактивен 1 | 01 май 2012 г. 01:02:56-0700 | 01 май 2012 г. 01:05:55-0700 | 179 || NonIdle 1 | 01 май 2012 г. 01:07:00-0700 | 01 май 2012 г. 01:10:15-0700 | 195 || Неактивен 2 | 01 май 2012 г. 01:11:20-0700 | 01 май 2012 г. 01:14:20-0700 | 180 || NonIdle 2 | 01 май 2012 г. 01:15:20-0700 | 01 май 2012 г. 01:15:20-0700 | 0 |Вижте напредъка на заявката тук:http://www.sqlfiddle.com/#!2 /e9372/1
Как работи:
Пет стъпки.
Първо, отделете неактивните от неактивните:
изберете *, @idle_state :=if(rpm между 800 и 900, 1, 0) като idle_statefrom (tbl, (изберете @state_group :=0 като y) като vars)order by tbl.timeStamp;код>
Изход:
<предварителен код>| КЛАПО | RPM | Y | IDLE_STATE ||----------------------------|------|---|------- -----|| 01 май 2012 г. 01:02:56-0700 | 802 | 0 | 1 || 01 май 2012 г. 01:03:45-0700 | 845 | 0 | 1 || 01 май 2012 г. 01:04:50-0700 | 825 | 0 | 1 || 01 май 2012 г. 01:05:55-0700 | 810 | 0 | 1 || 01 май 2012 г. 01:07:00-0700 | 1000 | 0 | 0 || 01 май 2012 г. 01:08:03-0700 | 1005 | 0 | 0 || 01 май 2012 г. 01:09:05-0700 | 1145 | 0 | 0 || 01 май 2012 г. 01:10:15-0700 | 1110 | 0 | 0 || 01 май 2012 г. 01:11:20-0700 | 800 | 0 | 1 || 01 май 2012 г. 01:12:22-0700 | 812 | 0 | 1 || 01 май 2012 г. 01:13:20-0700 | 820 | 0 | 1 || 01 май 2012 г. 01:14:20-0700 | 820 | 0 | 1 || 01 май 2012 г. 01:15:20-0700 | 1200 | 0 | 0 |Второ, разделете промените в групи:
изберете *, @idle_state :=if(rpm между 800 и 900, 1, 0) като idle_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) като state_group, @prev_state :=@idle_statefrom (tbl, (изберете @state_group :=0 като y) като променливи) подреждане по tbl.timeStamp;
Изход:
<предварителен код>| КЛАПО | RPM | Y | IDLE_STATE | STATE_GROUP | @PREV_STATE :=@IDLE_STATE ||-----------------------------------|------|---|-- ----------|-------------|----------------------- ---|| 01 май 2012 г. 01:02:56-0700 | 802 | 0 | 1 | 1 | 1 || 01 май 2012 г. 01:03:45-0700 | 845 | 0 | 1 | 1 | 1 || 01 май 2012 г. 01:04:50-0700 | 825 | 0 | 1 | 1 | 1 || 01 май 2012 г. 01:05:55-0700 | 810 | 0 | 1 | 1 | 1 || 01 май 2012 г. 01:07:00-0700 | 1000 | 0 | 0 | 2 | 0 || 01 май 2012 г. 01:08:03-0700 | 1005 | 0 | 0 | 2 | 0 || 01 май 2012 г. 01:09:05-0700 | 1145 | 0 | 0 | 2 | 0 || 01 май 2012 г. 01:10:15-0700 | 1110 | 0 | 0 | 2 | 0 || 01 май 2012 г. 01:11:20-0700 | 800 | 0 | 1 | 3 | 1 || 01 май 2012 г. 01:12:22-0700 | 812 | 0 | 1 | 3 | 1 || 01 май 2012 г. 01:13:20-0700 | 820 | 0 | 1 | 3 | 1 || 01 май 2012 г. 01:14:20-0700 | 820 | 0 | 1 | 3 | 1 || 01 май 2012 г. 01:15:20-0700 | 1200 | 0 | 0 | 4 | 0 |Трето, групирайте ги и изчислете продължителността:
изберете state_group, idle_state, min(timeStamp) като startTime, max(timeStamp) като endTime, timestampdiff(second, min(timeStamp), max(timeStamp)) като durationfrom( select *, @idle_state :=if (rpm между 800 и 900, 1, 0) като idle_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) като state_group, @prev_state :=@idle_state от (tbl, (изберете @state_group :=0 като y) като vars) подреждане по tbl.timeStamp) като xgroup по state_group, idle_state;
Изход:
<предварителен код>| STATE_GROUP | IDLE_STATE | НАЧАЛЕН ЧАС | КРАЙНО ВРЕМЕ | ПРОДЪЛЖИТЕЛНОСТ ||-------------|------------|-------------------- --------|--------------------------|----------|| 1 | 1 | 01 май 2012 г. 01:02:56-0700 | 01 май 2012 г. 01:05:55-0700 | 179 || 2 | 0 | 01 май 2012 г. 01:07:00-0700 | 01 май 2012 г. 01:10:15-0700 | 195 || 3 | 1 | 01 май 2012 г. 01:11:20-0700 | 01 май 2012 г. 01:14:20-0700 | 180 || 4 | 0 | 01 май 2012 г. 01:15:20-0700 | 01 май 2012 г. 01:15:20-0700 | 0 |Четвърто, вземете броя неактивни и неактивни:
изберете @idle_count :=@idle_count + if(idle_state =1,1,0) като idle_count, @non_idle_count :=@non_idle_count + if(idle_state =0,1,0) като non_idle_count, state_group, idle_state , min(timeStamp) като startTime, max(timeStamp) като endTime, timestampdiff(second, min(timeStamp), max(timeStamp)) като durationfrom( select *, @idle_state :=if(rpm между 800 и 900, 1, 0 ) като idle_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) като state_group, @prev_state :=@idle_state от (tbl, (изберете @state_group :=0 като y) като vars) ред от tbl.timeStamp) като x,(изберете @idle_count :=0 като y, @non_idle_count :=0 като z) като varsgroup от state_group, idle_state;
Изход:
<предварителен код>| IDLE_COUNT | NON_IDLE_COUNT | STATE_GROUP | IDLE_STATE | НАЧАЛЕН ЧАС | КРАЙНО ВРЕМЕ | ПРОДЪЛЖИТЕЛНОСТ ||------------|----------------|-------------|--- ---------|--------------------------|----------- -----------------|----------|| 1 | 0 | 1 | 1 | 01 май 2012 г. 01:02:56-0700 | 01 май 2012 г. 01:05:55-0700 | 179 || 1 | 1 | 2 | 0 | 01 май 2012 г. 01:07:00-0700 | 01 май 2012 г. 01:10:15-0700 | 195 || 2 | 1 | 3 | 1 | 01 май 2012 г. 01:11:20-0700 | 01 май 2012 г. 01:14:20-0700 | 180 || 2 | 2 | 4 | 0 | 01 май 2012 г. 01:15:20-0700 | 01 май 2012 г. 01:15:20-0700 | 0 |Накрая премахнете етапните променливи:
изберете if(idle_state =1, concat('Idle ', idle_count), concat('NonIdle ', non_idle_count) ) като Period, startTime, endTime, durationfrom( select @idle_count :=@idle_count + if( idle_state =1,1,0) като idle_count, @non_idle_count :=@non_idle_count +if(idle_state =0,1,0) като non_idle_count, state_group, idle_state, min(timeStamp) като startTime, max(timeStamp) като endTime, timestampdiff (секунда, min(timeStamp), max(timeStamp)) като продължителност от ( select *, @idle_state :=if(rpm между 800 и 900, 1, 0) as idle_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) като state_group, @prev_state :=@idle_state от (tbl, (изберете @state_group :=0 като y) като vars) подреждане по tbl.timeStamp ) като x,(изберете @idle_count :=0 като y, @non_idle_count :=0 като z) като vars група по state_group, idle_state) като резюме
Изход:
<предварителен код>| ПЕРИОД | НАЧАЛЕН ЧАС | КРАЙНО ВРЕМЕ | ПРОДЪЛЖИТЕЛНОСТ ||-----------|----------------------------|------ ----------------------|----------|| Неактивен 1 | 01 май 2012 г. 01:02:56-0700 | 01 май 2012 г. 01:05:55-0700 | 179 || NonIdle 1 | 01 май 2012 г. 01:07:00-0700 | 01 май 2012 г. 01:10:15-0700 | 195 || Неактивен 2 | 01 май 2012 г. 01:11:20-0700 | 01 май 2012 г. 01:14:20-0700 | 180 || NonIdle 2 | 01 май 2012 г. 01:15:20-0700 | 01 май 2012 г. 01:15:20-0700 | 0 |Вижте напредъка на заявката тук:http://www.sqlfiddle.com/#!2/ e9372/1
АКТУАЛИЗАЦИЯ
Заявката може да бъде съкратена http://www.sqlfiddle.com/#!2/418cb /1
Ако забележите, номерът на периода просто идва в тандем (неактивен-неактивен, празен-неактивен и т.н.). Можете просто да направите това:
изберете случай, когато idle_state then concat('Idle ', @rn :=@rn + 1) else concat('Non-idle', @rn ) end as Period, min(timeStamp) as startTime, max (timeStamp) като endTime, timestampdiff(second, min(timeStamp), max(timeStamp)) като durationfrom( select *, @idle_state :=if(rpm между 800 и 900, 1, 0) като idle_state, @state_group :=@ state_group + if(@idle_state =@prev_state,0,1) като state_group, @prev_state :=@idle_state от (tbl, (изберете @state_group :=0 като y) като vars) подреждане по tbl.timeStamp) като x,( изберете @rn :=0) като rxgroup от state_group, idle_state
Изход:
<предварителен код>| ПЕРИОД | НАЧАЛЕН ЧАС | КРАЙНО ВРЕМЕ | ПРОДЪЛЖИТЕЛНОСТ ||------------|----------------------------|----- -----------------------|----------|| Неактивен 1 | 01 май 2012 г. 01:02:56-0700 | 01 май 2012 г. 01:05:55-0700 | 179 || Без празен ход 1 | 01 май 2012 г. 01:07:00-0700 | 01 май 2012 г. 01:10:15-0700 | 195 || Неактивен 2 | 01 май 2012 г. 01:11:20-0700 | 01 май 2012 г. 01:14:20-0700 | 180 || Без празен ход 2 | 01 май 2012 г. 01:15:20-0700 | 01 май 2012 г. 01:15:20-0700 | 0 |