sql >> Database teknologi >  >> RDS >> Mysql

mysql-gruppering, mens en værdi er i et interval

Prøv dette:http://www.sqlfiddle.com/#!2/e9372/ 1

Fordelen ved at gøre det på DB-siden er, at du kan komme til at bruge forespørgslen ikke kun på PHP, du kan også bruge det på Java, C#, Python osv. Og det er hurtigt at gøre det på DB-siden

vælg if(idle_state =1, concat('Idle ', idle_count), concat('NonIdle ', non_idle_count) ) som Periode, startTime, endTime, durationfrom( vælg @idle_count :=@idle_count + if( idle_state =1,1,0) som idle_count, @non_idle_count :=@non_idle_count +if(idle_state =0,1,0) som non_idle_count, state_group, indle_state, min(timeStamp) as startTime, max(timeStamp) as endTime, timestampdiff (second, min(timeStamp), max(timeStamp)) som varighed fra (vælg *, @idle_state :=if(rpm mellem 800 og 900, 1, 0) som idle_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) som state_group, @prev_state :=@idle_state fra (tbl, (vælg @state_group :=0 som y) som vars) sorter efter tbl.timeStamp ) som x ,(vælg @idle_count :=0 som y, @non_idle_count :=0 som z) som vars group by state_group, indle_state) som resumé 

Output:

| PERIODE | STARTTID | SLUTTID | VARIGHED ||-----------|--------------------------------|----- ----------------------|--------|| Tomgang 1 | 1. maj 2012 01:02:56-0700 | 1. maj 2012 01:05:55-0700 | 179 || Ikke tomgang 1 | 1. maj 2012 01:07:00-0700 | 1. maj 2012 01:10:15-0700 | 195 || Tomgang 2 | 1. maj 2012 01:11:20-0700 | 1. maj 2012 01:14:20-0700 | 180 || NonIdle 2 | 1. maj 2012 01:15:20-0700 | 1. maj 2012 01:15:20-0700 | 0 |

Se forespørgselsforløbet her:http://www.sqlfiddle.com/#!2 /e9372/1

Sådan virker det:

Fem trin.

Først skal du adskille tomgang fra ikke-tomgang:

vælg *, @idle_state :=if(rpm mellem 800 og 900, 1, 0) som idle_statefra (tbl, (vælg @state_group :=0 som y) som vars)bestil efter tbl.timeStamp; 

Output:

| TIDSSTIMPEL | RPM | Y | IDLE_STATE ||-----------------------------|------|---|------- -----|| 1. maj 2012 01:02:56-0700 | 802 | 0 | 1 || 1. maj 2012 01:03:45-0700 | 845 | 0 | 1 || 1. maj 2012 01:04:50-0700 | 825 | 0 | 1 || 1. maj 2012 01:05:55-0700 | 810 | 0 | 1 || 1. maj 2012 01:07:00-0700 | 1000 | 0 | 0 || 1. maj 2012 01:08:03-0700 | 1005 | 0 | 0 || 1. maj 2012 01:09:05-0700 | 1145 | 0 | 0 || 1. maj 2012 01:10:15-0700 | 1110 | 0 | 0 || 1. maj 2012 01:11:20-0700 | 800 | 0 | 1 || 1. maj 2012 01:12:22-0700 | 812 | 0 | 1 || 1. maj 2012 01:13:20-0700 | 820 | 0 | 1 || 1. maj 2012 01:14:20-0700 | 820 | 0 | 1 || 1. maj 2012 01:15:20-0700 | 1200 | 0 | 0 |

For det andet skal du adskille ændringerne i grupper:

vælg *, @idle_state :=if(rpm mellem 800 og 900, 1, 0) som inaktiv_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) som state_group, @prev_state :=@idle_statefrom (tbl, (vælg @state_group :=0 som y) som vars)bestil efter tbl.timeStamp; 

Output:

| TIDSSTIMPEL | RPM | Y | IDLE_STATE | STATE_GROUP | @PREV_STATE :=@IDLE_STATE ||----------------------------------|------|---|-- ----------|-------------|------------------------ ---|| 1. maj 2012 01:02:56-0700 | 802 | 0 | 1 | 1 | 1 || 1. maj 2012 01:03:45-0700 | 845 | 0 | 1 | 1 | 1 || 1. maj 2012 01:04:50-0700 | 825 | 0 | 1 | 1 | 1 || 1. maj 2012 01:05:55-0700 | 810 | 0 | 1 | 1 | 1 || 1. maj 2012 01:07:00-0700 | 1000 | 0 | 0 | 2 | 0 || 1. maj 2012 01:08:03-0700 | 1005 | 0 | 0 | 2 | 0 || 1. maj 2012 01:09:05-0700 | 1145 | 0 | 0 | 2 | 0 || 1. maj 2012 01:10:15-0700 | 1110 | 0 | 0 | 2 | 0 || 1. maj 2012 01:11:20-0700 | 800 | 0 | 1 | 3 | 1 || 1. maj 2012 01:12:22-0700 | 812 | 0 | 1 | 3 | 1 || 1. maj 2012 01:13:20-0700 | 820 | 0 | 1 | 3 | 1 || 1. maj 2012 01:14:20-0700 | 820 | 0 | 1 | 3 | 1 || 1. maj 2012 01:15:20-0700 | 1200 | 0 | 0 | 4 | 0 |

For det tredje, grupper dem, og udregn varigheden:

vælg state_group, indle_state, min(timeStamp) som startTime, max(timeStamp) som endTime, timestampdiff(second, min(timeStamp), max(timeStamp)) som durationfrom( vælg *, @idle_state :=hvis (rpm mellem 800 og 900, 1, 0) som idle_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) som state_group, @prev_state :=@idle_state from (tbl, (vælg @state_group) :=0 som y) som vars) sorteres efter tbl.timeStamp) som xgroup efter state_group, indle_state; 

Output:

| STATE_GROUP | IDLE_STATE | STARTTID | SLUTTID | VARIGHED ||-------------|----------------|------------------- --------|------------------------------------|--------|| 1 | 1 | 1. maj 2012 01:02:56-0700 | 1. maj 2012 01:05:55-0700 | 179 || 2 | 0 | 1. maj 2012 01:07:00-0700 | 1. maj 2012 01:10:15-0700 | 195 || 3 | 1 | 1. maj 2012 01:11:20-0700 | 1. maj 2012 01:14:20-0700 | 180 || 4 | 0 | 1. maj 2012 01:15:20-0700 | 1. maj 2012 01:15:20-0700 | 0 |

For det fjerde, få tallet for tomgang og ikke-tomgang:

vælg @idle_count :=@idle_count + if(idle_state =1,1,0) som indle_count, @non_idle_count :=@non_idle_count + if(idle_state =0,1,0) as non_idle_count, state_group, indle_state , min(timeStamp) som startTime, max(timeStamp) som endTime, timestampdiff(second, min(timeStamp), max(timeStamp)) som durationfrom( vælg *, @idle_state :=if(rpm mellem 800 og 900, 1, 0 ) som idle_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) as state_group, @prev_state :=@idle_state fra (tbl, (vælg @state_group :=0 som y) som vars) rækkefølge af tbl.timeStamp) som x,(vælg @idle_count :=0 som y, @non_idle_count :=0 som z) som varsgroup by state_group, indle_state; 

Output:

| IDLE_COUNT | NON_IDLE_COUNT | STATE_GROUP | IDLE_STATE | STARTTID | SLUTTID | VARIGHED ||------------|----------------|------------------|--- ----------|--------------------------------|---------------- ------------------|--------|| 1 | 0 | 1 | 1 | 1. maj 2012 01:02:56-0700 | 1. maj 2012 01:05:55-0700 | 179 || 1 | 1 | 2 | 0 | 1. maj 2012 01:07:00-0700 | 1. maj 2012 01:10:15-0700 | 195 || 2 | 1 | 3 | 1 | 1. maj 2012 01:11:20-0700 | 1. maj 2012 01:14:20-0700 | 180 || 2 | 2 | 4 | 0 | 1. maj 2012 01:15:20-0700 | 1. maj 2012 01:15:20-0700 | 0 |

Til sidst skal du fjerne iscenesættelsesvariablerne:

vælg if(idle_state =1, concat('Idle ', idle_count), concat('NonIdle ', non_idle_count) ) som Periode, startTime, endTime, durationfrom( vælg @idle_count :=@idle_count + if( idle_state =1,1,0) som idle_count, @non_idle_count :=@non_idle_count +if(idle_state =0,1,0) som non_idle_count, state_group, indle_state, min(timeStamp) as startTime, max(timeStamp) as endTime, timestampdiff (second, min(timeStamp), max(timeStamp)) som varighed fra (vælg *, @idle_state :=if(rpm mellem 800 og 900, 1, 0) som idle_state, @state_group :=@state_group + if(@idle_state =@prev_state,0,1) som state_group, @prev_state :=@idle_state fra (tbl, (vælg @state_group :=0 som y) som vars) sorter efter tbl.timeStamp ) som x ,(vælg @idle_count :=0 som y, @non_idle_count :=0 som z) som vars group by state_group, indle_state) som resumé 

Output:

| PERIODE | STARTTID | SLUTTID | VARIGHED ||-----------|--------------------------------|----- ----------------------|--------|| Tomgang 1 | 1. maj 2012 01:02:56-0700 | 1. maj 2012 01:05:55-0700 | 179 || Ikke tomgang 1 | 1. maj 2012 01:07:00-0700 | 1. maj 2012 01:10:15-0700 | 195 || Tomgang 2 | 1. maj 2012 01:11:20-0700 | 1. maj 2012 01:14:20-0700 | 180 || NonIdle 2 | 1. maj 2012 01:15:20-0700 | 1. maj 2012 01:15:20-0700 | 0 |

Se forespørgselsforløbet her:http://www.sqlfiddle.com/#!2/ e9372/1

OPDATERING

Forespørgsel kunne forkortes http://www.sqlfiddle.com/#!2/418cb /1

Hvis du vil bemærke, kommer periodenummeret bare i tandem (tomgang-ikke-Idle, inaktiv-ikke-Idle, og så videre). Du kan bare gøre dette:

vælg store og små bogstaver, når idle_state derefter concat('Idle ', @rn :=@rn + 1) else concat('Non-idle ', @rn ) slutter som Periode, min(timeStamp) som startTime, max. (timeStamp) som slutTime, timestampdiff(second, min(timeStamp), max(timeStamp)) as durationfrom( vælg *, @idle_state :=if(rpm mellem 800 og 900, 1, 0) som inaktiv_tilstand, @state_group :=@ state_group + if(@idle_state =@prev_state,0,1) as state_group, @prev_state :=@idle_state from (tbl, (vælg @state_group :=0 som y) som vars) sorteret efter tbl.timeStamp) som x,( vælg @rn :=0) som rxgroup efter state_group, indle_state 

Output:

| PERIODE | STARTTID | SLUTTID | VARIGHED ||------------|--------------------------------|----- -----------------------|--------|| Tomgang 1 | 1. maj 2012 01:02:56-0700 | 1. maj 2012 01:05:55-0700 | 179 || Ikke-tomgang 1 | 1. maj 2012 01:07:00-0700 | 1. maj 2012 01:10:15-0700 | 195 || Tomgang 2 | 1. maj 2012 01:11:20-0700 | 1. maj 2012 01:14:20-0700 | 180 || Ikke-tomgang 2 | 1. maj 2012 01:15:20-0700 | 1. maj 2012 01:15:20-0700 | 0 |

  1. Kæmper virkelig med CONCAT_WS ... vær venlig at hjælpe en nybegynder :)

  2. Yii-model med sammensat primærnøgle

  3. SQL-funktioner - faktoriel

  4. Sådan ændres sproget for din Oracle-session