sql >> Database >  >> RDS >> Mysql

mysql-groepering terwijl een waarde in een bereik ligt

Probeer dit:http://www.sqlfiddle.com/#!2/e9372/ 1

Het voordeel van het doen aan DB-kant is dat je de query niet alleen op PHP kunt gebruiken, je kunt het ook gebruiken op Java, C#, Python, enz. En het is snel om het aan de DB-kant te doen

select 
  if(idle_state = 1, 
       concat('Idle ', idle_count), 
       concat('NonIdle ', non_idle_count) ) as Period,
  startTime, endTime, duration
from
(

  select 

    @idle_count := @idle_count + if(idle_state = 1,1,0) as idle_count,
    @non_idle_count := @non_idle_count +if(idle_state = 0,1,0) as non_idle_count,

    state_group, idle_state,
    min(timeStamp) as startTime, max(timeStamp) as endTime,
    timestampdiff(second, min(timeStamp), max(timeStamp)) as duration
  from
  (
    select *,        
      @idle_state := if(rpm between 800 and 900, 1, 0) as idle_state,
      @state_group := @state_group + 
                      if(@idle_state = @prev_state,0,1) as state_group,
      @prev_state := @idle_state
    from (tbl, (select @state_group := 0 as y) as vars)
    order by tbl.timeStamp
  ) as x
  ,(select @idle_count := 0 as y, @non_idle_count := 0 as z) as vars
  group by state_group, idle_state

) as summary

Uitgang:

|    PERIOD |                  STARTTIME |                    ENDTIME | DURATION |
|-----------|----------------------------|----------------------------|----------|
|    Idle 1 | May, 01 2012 01:02:56-0700 | May, 01 2012 01:05:55-0700 |      179 |
| NonIdle 1 | May, 01 2012 01:07:00-0700 | May, 01 2012 01:10:15-0700 |      195 |
|    Idle 2 | May, 01 2012 01:11:20-0700 | May, 01 2012 01:14:20-0700 |      180 |
| NonIdle 2 | May, 01 2012 01:15:20-0700 | May, 01 2012 01:15:20-0700 |        0 |

Bekijk hier de voortgang van de zoekopdracht:http://www.sqlfiddle.com/#!2 /e9372/1

Hoe het werkt:

Vijf stappen.

Scheid eerst de inactieve van de niet-inactieve:

select *,
  @idle_state := if(rpm between 800 and 900, 1, 0) as idle_state
from (tbl, (select @state_group := 0 as y) as vars)
order by tbl.timeStamp;

Uitgang:

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

Ten tweede, verdeel de wijzigingen in groepen:

select *,  
  @idle_state := if(rpm between 800 and 900, 1, 0) as idle_state,
  @state_group := @state_group + 
                  if(@idle_state = @prev_state,0,1) as state_group,
  @prev_state := @idle_state

from (tbl, (select @state_group := 0 as y) as vars)
order by tbl.timeStamp;

Uitgang:

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

Ten derde, groepeer ze en bereken de duur:

select 
  state_group, idle_state,
  min(timeStamp) as startTime, max(timeStamp) as endTime,
  timestampdiff(second, min(timeStamp), max(timeStamp)) as duration
from
(
  select *,    
    @idle_state := if(rpm between 800 and 900, 1, 0) as idle_state,
    @state_group := @state_group + 
                    if(@idle_state = @prev_state,0,1) as state_group,
    @prev_state := @idle_state
  from (tbl, (select @state_group := 0 as y) as vars)
  order by tbl.timeStamp
) as x
group by state_group, idle_state;

Uitgang:

| STATE_GROUP | IDLE_STATE |                  STARTTIME |                    ENDTIME | DURATION |
|-------------|------------|----------------------------|----------------------------|----------|
|           1 |          1 | May, 01 2012 01:02:56-0700 | May, 01 2012 01:05:55-0700 |      179 |
|           2 |          0 | May, 01 2012 01:07:00-0700 | May, 01 2012 01:10:15-0700 |      195 |
|           3 |          1 | May, 01 2012 01:11:20-0700 | May, 01 2012 01:14:20-0700 |      180 |
|           4 |          0 | May, 01 2012 01:15:20-0700 | May, 01 2012 01:15:20-0700 |        0 |

Ten vierde, krijg de inactieve en niet-inactieve telling:

select 

  @idle_count := @idle_count + if(idle_state = 1,1,0) as idle_count,
  @non_idle_count := @non_idle_count + if(idle_state = 0,1,0) as non_idle_count,

  state_group, idle_state,
  min(timeStamp) as startTime, max(timeStamp) as endTime,
  timestampdiff(second, min(timeStamp), max(timeStamp)) as duration
from
(
  select *,        
    @idle_state := if(rpm between 800 and 900, 1, 0) as idle_state,
    @state_group := @state_group + 
                    if(@idle_state = @prev_state,0,1) as state_group,
    @prev_state := @idle_state
  from (tbl, (select @state_group := 0 as y) as vars)
  order by tbl.timeStamp
) as x
,(select @idle_count := 0 as y, @non_idle_count := 0 as z) as vars
group by state_group, idle_state;

Uitgang:

| IDLE_COUNT | NON_IDLE_COUNT | STATE_GROUP | IDLE_STATE |                  STARTTIME |                    ENDTIME | DURATION |
|------------|----------------|-------------|------------|----------------------------|----------------------------|----------|
|          1 |              0 |           1 |          1 | May, 01 2012 01:02:56-0700 | May, 01 2012 01:05:55-0700 |      179 |
|          1 |              1 |           2 |          0 | May, 01 2012 01:07:00-0700 | May, 01 2012 01:10:15-0700 |      195 |
|          2 |              1 |           3 |          1 | May, 01 2012 01:11:20-0700 | May, 01 2012 01:14:20-0700 |      180 |
|          2 |              2 |           4 |          0 | May, 01 2012 01:15:20-0700 | May, 01 2012 01:15:20-0700 |        0 |

Verwijder ten slotte de staging-variabelen:

select 
  if(idle_state = 1, 
       concat('Idle ', idle_count), 
       concat('NonIdle ', non_idle_count) ) as Period,
  startTime, endTime, duration
from
(

  select 

    @idle_count := @idle_count + if(idle_state = 1,1,0) as idle_count,
    @non_idle_count := @non_idle_count +if(idle_state = 0,1,0) as non_idle_count,

    state_group, idle_state,
    min(timeStamp) as startTime, max(timeStamp) as endTime,
    timestampdiff(second, min(timeStamp), max(timeStamp)) as duration
  from
  (
    select *,        
      @idle_state := if(rpm between 800 and 900, 1, 0) as idle_state,
      @state_group := @state_group + 
                      if(@idle_state = @prev_state,0,1) as state_group,
      @prev_state := @idle_state
    from (tbl, (select @state_group := 0 as y) as vars)
    order by tbl.timeStamp
  ) as x
  ,(select @idle_count := 0 as y, @non_idle_count := 0 as z) as vars
  group by state_group, idle_state

) as summary

Uitgang:

|    PERIOD |                  STARTTIME |                    ENDTIME | DURATION |
|-----------|----------------------------|----------------------------|----------|
|    Idle 1 | May, 01 2012 01:02:56-0700 | May, 01 2012 01:05:55-0700 |      179 |
| NonIdle 1 | May, 01 2012 01:07:00-0700 | May, 01 2012 01:10:15-0700 |      195 |
|    Idle 2 | May, 01 2012 01:11:20-0700 | May, 01 2012 01:14:20-0700 |      180 |
| NonIdle 2 | May, 01 2012 01:15:20-0700 | May, 01 2012 01:15:20-0700 |        0 |

Bekijk de voortgang van de zoekopdracht hier:http://www.sqlfiddle.com/#!2/ e9372/1

UPDATE

Query kan worden ingekort http://www.sqlfiddle.com/#!2/418cb /1

Als u opmerkt, komt het periodenummer gewoon in tandem (inactief-niet-actief, inactief-niet-actief, enzovoort). Je kunt dit gewoon doen:

select 


  case when idle_state then
     concat('Idle ', @rn := @rn + 1) 
  else
     concat('Non-idle ', @rn )
  end as Period,


  min(timeStamp) as startTime, max(timeStamp) as endTime,

  timestampdiff(second, min(timeStamp), max(timeStamp)) as duration

from
(
  select *,        
  @idle_state := if(rpm between 800 and 900, 1, 0) as idle_state,
  @state_group := @state_group + if(@idle_state = @prev_state,0,1) as state_group,
  @prev_state := @idle_state
  from (tbl, (select @state_group := 0 as y) as vars)
  order by tbl.timeStamp
) as x,
(select @rn := 0) as rx
group by state_group, idle_state

Uitgang:

|     PERIOD |                  STARTTIME |                    ENDTIME | DURATION |
|------------|----------------------------|----------------------------|----------|
|     Idle 1 | May, 01 2012 01:02:56-0700 | May, 01 2012 01:05:55-0700 |      179 |
| Non-idle 1 | May, 01 2012 01:07:00-0700 | May, 01 2012 01:10:15-0700 |      195 |
|     Idle 2 | May, 01 2012 01:11:20-0700 | May, 01 2012 01:14:20-0700 |      180 |
| Non-idle 2 | May, 01 2012 01:15:20-0700 | May, 01 2012 01:15:20-0700 |        0 |


  1. Een module ontwikkelen met Java 9 in Eclipse IDE, deel 2

  2. Vreemde vergelijking met postgresql

  3. hoe het databaseschema correct te specificeren in springboot?

  4. Waarom wordt de uitvoeringstijd van de opgeslagen procedure in Oracle aanzienlijk verlengd, afhankelijk van hoe deze wordt uitgevoerd?