2015-01-13 1 views
3

저는 MySQL을 사용하고 특정 시간에 서비스가 위 또는 아래에 있는지 여부를 결정하는 모니터의 결과를 저장하는 '결과'테이블을 가지고 있습니다.MySQL은 연속 된 동일한 결과에 대해 첫 번째와 마지막 레코드를 반환합니다.

+-----------+------------+---------------------+--------+ 
| result_id | service_id | time_stamp   | result | 
+-----------+------------+---------------------+--------+ 
|  1  |  1 | 0000-00-00 00:01:00 | down | 
|  2  |  1 | 0000-00-00 00:02:00 | up  | 
|  3  |  1 | 0000-00-00 00:03:00 | up  | 
|  4  |  1 | 0000-00-00 00:04:00 | up  | 
|  5  |  1 | 0000-00-00 00:05:00 | down | 
|  6  |  1 | 0000-00-00 00:06:00 | down | 
|  7  |  1 | 0000-00-00 00:07:00 | up  | 
|  8  |  1 | 0000-00-00 00:08:00 | down | 
|  9  |  1 | 0000-00-00 00:09:00 | up  | 
|  10 |  2 | 0000-00-00 00:03:00 | up  | 
+-----------+------------+---------------------+--------+ 

나는 주어진 서비스에 대한 결과에 보이는 결과의 표를 얻을이 처음 아래있는 마지막 시간 (연속)과 최대 것에 대한 반대로 기록 된 시간을 반환합니다. 이렇게하면 서비스 중단 시간을 기록하는 데 도움이됩니다.

내가 찾고있는 결과는 다음과 같습니다. SERVICE_ID 경우 1

...

+-----------------------+---------------------+--------+ 
| start_time   | end_time   | result | 
+-----------------------+---------------------+--------+ 
| 0000-00-00 00:01:00 | 0000-00-00 00:01:00 | down | 
| 0000-00-00 00:02:00 | 0000-00-00 00:04:00 | up  | 
| 0000-00-00 00:05:00 | 0000-00-00 00:06:00 | down | 
| 0000-00-00 00:07:00 | 0000-00-00 00:07:00 | up  | 
| 0000-00-00 00:08:00 | 0000-00-00 00:08:00 | down | 
| 0000-00-00 00:09:00 | 0000-00-00 00:09:00 | up  | 
+-----------------------+---------------------+--------+ 

나는 비교적 쉽게 자바 나 PHP에서이 정보를 얻을 수있을 것입니다하지만 난 SQL 쿼리를 사용하는 것을 선호합니다. 내 SQL 기술은 특별히 향상되지 않습니다. 어떻게 접근할까요?

+0

: http://stackoverflow.com/questions/13317206/mysql-group-by-consecutive-rows – Robert

+0

감사합니다! 이 솔루션을 살펴 보았지만 결과가 단일 행으로 연결되지 않았습니다. 솔루션 중 하나에서 기본 키가 타임 스탬프와 혼동을 느낀 것 같습니다. – UsainBloot

답변

3

가장 쉬운 접근 방법은 변수를 사용하는 것입니다. 가장 쉬운 방법은 두 개의 변수를 추가하는 것입니다. 하나는 "위로"의 숫자이고 다른 하나는 "아래로"의 수를 지정하는 것입니다. 주어진 업 시퀀스는 선행하는 "다운"수에 대해 일정한 값을 가지며 그 반대의 경우도 마찬가지입니다. 이 논리를 집계에 사용할 수 있습니다.

결과 쿼리는 : 그것은 당신을 도울 수

select result, min(time_stamp) as start_time, max(time_stamp) as end_time 
from (select r.*, 
      (@ups := @ups + (result = 'up')) as ups, 
      (@downs := @downs + (result = 'down')) as downs 
     from results r cross join 
      (select @ups := 0, @downs := 0) vars 
     where service_id = 1 
     order by time_stamp 
    ) r 
group by result, (case when result = 'up' then downs else ups end);