How do I group on continuous ranges (mysql 5.7)

I want to return an array of date ranges when the site is down.

I am using MySQL 5.7.

Table down_time

created_at           user_id down
2017-12-15 14:50:21    1       1
2017-12-21 19:19:19    1       0
2017-12-25 22:41:14    1       1
2017-12-25 22:41:17    1       0
2017-12-25 23:11:22    1       0
2017-12-25 23:11:24    1       1
2017-12-25 23:31:24    1       1

Here at the bottom of the column - 0 (false) is displayed down and 1 (true) represents up. I need a view / result like this:

down                  up                     user_id 
2017-12-21 19:19:19   2017-12-25 22:41:14    1
2017-12-25 22:41:17   2017-12-25 23:11:24    1      

Hope this example fully matches my needs - I only need downtime ranges.

If this can be achieved using Laravel's helper SQL query methods (5.5), that would be great (so I can easily add query selectors such as ->where('user_id', Auth::user()->id)->whereBetween('created_at', [$range['from'], $range['to']])), but I'm not picky in this situation - raw MySQL (5.7.19) will also wonderful.

+6
2

, MySQL, :

select user_id, min(created_at) as ca_0, created_at_1 as ca_1
from (select t.*,
             (select min(t2.created_at)
              from t t2
              where t2.user_id = t.user_id and t2.down = 1 and
                    t2.created_at > t.created_at
             ) as created_at_1
      from t
      where t.down = 0
     ) tt
group by user_id, created_at_1;

, Laravel.

+4

, user_id, mysql. :

 $range = request('range');
        $range_from = $range['from'];
        $range_to = $range['to'];
        $user_id = Auth::user()->id;
        return DB::select("select user_id, min(created_at) as ca_0, created_at_1 as ca_1
from (select down_time.*,
             (select min(t2.created_at)
              from down_time t2
              where t2.user_id = $user_id and t2.down = 1 and
                    t2.created_at > down_time.created_at and 
                    t2.created_at between '$range_from' and '$range_to'
             ) as created_at_1
      from down_time
      where down_time.down = 0 and down_time.user_id = $user_id and 
      down_time.created_at between '$range_from' and '$range_to'
     ) tt
group by user_id, created_at_1;");
0

All Articles