Yogesh
Yogesh

Reputation: 33

select timestamp values between time durations where a column has 0 in MySQL

I want to select the time limits(stamp_date) when the uptime has 0 or continues to be in 0.

TABLE:

CREATE TABLE IF NOT EXISTS sample (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    sname VARCHAR(30) NULL,
    uptime BIGINT,
    stamp_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
);

INSERT statements:

insert into sample values(null,'hi',10,'2015-01-08 05:30:00');
insert into sample values(null,'hi',20,'2015-01-08 05:40:00');
insert into sample values(null,'hi',30,'2015-01-08 05:50:00');
insert into sample values(null,'hi',40,'2015-01-08 06:00:00');
insert into sample values(null,'hi',50,'2015-01-08 06:10:00');
insert into sample values(null,'hi',0,'2015-01-08 06:20:00');
insert into sample values(null,'hi',10,'2015-01-08 06:30:00');
insert into sample values(null,'hi',20,'2015-01-08 06:40:00');
insert into sample values(null,'hi',30,'2015-01-08 06:50:00');
insert into sample values(null,'hi',40,'2015-01-08 07:00:00');
insert into sample values(null,'hi',0,'2015-01-08 07:10:00');
insert into sample values(null,'hi',0,'2015-01-08 07:20:00');
insert into sample values(null,'hi',0,'2015-01-08 07:30:00');
insert into sample values(null,'hi',0,'2015-01-08 07:40:00');
insert into sample values(null,'hi',0,'2015-01-08 07:50:00');
insert into sample values(null,'hi',10,'2015-01-08 08:00:00');
insert into sample values(null,'hi',20,'2015-01-08 08:10:00');
insert into sample values(null,'hi',0,'2015-01-08 08:20:00');
insert into sample values(null,'hi',40,'2015-01-08 08:30:00');

sample table:

mysql> select * from sample;
+----+-------+-------+---------------------+
| id | sname | uptime| stamp_date          |
+----+-------+-------+---------------------+
|  1 | hi    |    10 | 2015-01-08 05:30:00 |
|  2 | hi    |    20 | 2015-01-08 05:40:00 |
|  3 | hi    |    30 | 2015-01-08 05:50:00 |
|  4 | hi    |    40 | 2015-01-08 06:00:00 |
|  5 | hi    |    50 | 2015-01-08 06:10:00 |
|  6 | hi    |     0 | 2015-01-08 06:20:00 |
|  7 | hi    |    10 | 2015-01-08 06:30:00 |
|  8 | hi    |    20 | 2015-01-08 06:40:00 |
|  9 | hi    |    30 | 2015-01-08 06:50:00 |
| 10 | hi    |    40 | 2015-01-08 07:00:00 |
| 11 | hi    |     0 | 2015-01-08 07:10:00 |
| 12 | hi    |     0 | 2015-01-08 07:20:00 |
| 13 | hi    |     0 | 2015-01-08 07:30:00 |
| 14 | hi    |     0 | 2015-01-08 07:40:00 |
| 15 | hi    |     0 | 2015-01-08 07:50:00 |
| 16 | hi    |    10 | 2015-01-08 08:00:00 |
| 17 | hi    |    20 | 2015-01-08 08:10:00 |
| 18 | hi    |     0 | 2015-01-08 08:20:00 |
| 19 | hi    |    40 | 2015-01-08 08:30:00 |
+----+-------+-------+---------------------+
19 rows in set (0.00 sec)

1) The link was down (uptime=0) between 06:20:00 to 06:30:00

2) The link was down (uptime=0) between 07:10:00 to 08:00:00

3) The link was down (uptime=0) between 08:20:00 to 08:30:00

Expected result should be like the below:

+++++++++++++++++++++++++
| When Uptime is 0      |
+++++++++++++++++++++++++
|  06:20:00 to 06:30:00 |
|  07:10:00 to 08:00:00 |
|  08:20:00 to 08:30:00 |
+++++++++++++++++++++++++ 

Could someone please help me to write a SQL or stored procedure to achieve the above result?

Thanks,

Yogesh

Upvotes: 2

Views: 94

Answers (2)

Zahid Ali
Zahid Ali

Reputation: 466

check this out on fiddle here is fiddle

SELECT 
  CONCAT(
    DATE_FORMAT(a.stamp_date, '%H:%i:%s'),
    ' to ',
    DATE_FORMAT(b.stamp_date, '%H:%i:%s')
  ) AS 'When Uptime is 0' 
FROM
  (SELECT 
    id,
    stamp_date 
  FROM
    sample 
  WHERE uptime = 0) AS a,
  (SELECT 
    id,
    stamp_date 
  FROM
    sample 
  WHERE uptime <> 0) AS b 
WHERE a.stamp_date < b.stamp_date 
AND a.id = b.id-1
GROUP BY a.id 

Upvotes: 0

Ishamael
Ishamael

Reputation: 12795

If your IDs have no holes in them (e.g. 18 is not followed by 20), then the following query will do the trick:

select concat(time(r.stamp_date), ' to ', 
       IFNULL((select time(min(stamp_date))
       from sample
       where id > r.id and uptime != 0
       ), "NOW")) `When Uptime is 0`
from sample l 
     join
     sample r 
     on l.id = r.id - 1
where l.uptime != 0 and r.uptime = 0;

This is what it returns for your data with an extra downtime entry at the end

+----------------------+ | When Uptime is 0 | +----------------------+ | 06:20:00 to 06:30:00 | | 07:10:00 to 08:00:00 | | 08:20:00 to 08:30:00 | | 08:40:00 to NOW | +----------------------+ 4 rows in set (0.00 sec)

If your IDs do have holes, then you'll need to modify the ON condition a little bit

select concat(time(r.stamp_date), ' to ', 
       IFNULL((select time(min(stamp_date))
       from sample
       where id > r.id and uptime != 0
       ), "NOW")) `When Uptime is 0`
from sample l 
     join
     sample r 
     on l.id = (select max(id) from sample where id < r.id)
where l.uptime != 0 and r.uptime = 0;

Upvotes: 4

Related Questions