2017-01-17 1 views
2

다음 표가 있습니다. Exery의 경우 2,5 분 (150 초) 동안 두 개의 플랜트에 대해 하나의 레코드가 있습니다. 각 상태의 공장에서 max (datetime) 및 min (datetime)을 보여주는 결과를 얻고 싶습니다. 그러나 상태가 바뀔 때마다 새로운 라인이 있어야합니다.상태가 변경 될 때까지 동일한 상태의 행 그룹화

plant state unix_timest datetime 
    1 1  1452639750 2016-01-13 00:02:30 
    2 1  1452639750 2016-01-13 00:02:30 
    1 1  1452639900 2016-01-13 00:05:00 
    2 1  1452639900 2016-01-13 00:05:00 
    1 1  1452640050 2016-01-13 00:07:30 
    2 1  1452640050 2016-01-13 00:07:30 
    1 1  1452640200 2016-01-13 00:10:00 
    2 1  1452640200 2016-01-13 00:10:00 
    1 1  1452640350 2016-01-13 00:12:30 
    2 0  1452640350 2016-01-13 00:12:30 
    1 1  1452640500 2016-01-13 00:15:00 
    2 0  1452640500 2016-01-13 00:15:00 
    1 1  1452640650 2016-01-13 00:17:30 
    2 1  1452640650 2016-01-13 00:17:30 
    1 1  1452640800 2016-01-13 00:20:00 
    2 1  1452640800 2016-01-13 00:20:00 

내 SQL 문은 다음과 같습니다

SELECT a.line, a.current_state, min(a.`datetime`) AS mindate, max(a.`datetime`) AS maxdate 
    FROM `bde_production` 
    LEFT JOIN bde_production a ON a.unix_timestamp = bde_production.unix_timestamp 
    LEFT JOIN bde_production b ON b.unix_timestamp = bde_production.unix_timestamp -150 
    GROUP BY a.line, a.current_state ORDER BY a.line, mindate 

결과 : 내가 얻을하고자하는 어떤

plant current_state mindate    maxdate 
    1 1    2016-01-13 00:02:30 2016-01-13 00:20:00 
    2 1    2016-01-13 00:02:30 2016-01-13 00:20:00 
    2 0    2016-01-13 00:12:30 2016-01-13 00:15:00 

:

plant current_state mindate    maxdate 
    1 1    2016-01-13 00:02:30 2016-01-13 00:20:00 
    2 1    2016-01-13 00:02:30 2016-01-13 00:10:00 
    2 0    2016-01-13 00:12:30 2016-01-13 00:15:00 
    2 1    2016-01-13 00:17:30 2016-01-13 00:20:00 

감사

답변

-1

나는 거의 그와 결과를 얻었다 :

SELECT 
     d.plant, d.current_state, d.unix_timestamp, d.`datetime` 
    FROM 
     bde_production d 
      left join 
     bde_production d_prev 
      on 
      d_prev.line = d.line and 
      d_prev.unix_timestamp< (d.unix_timestamp) 
      left join 
     bde_production d_inter 
      on 
       d_prev.plant= d.plant and 
       d_inter.unix_timestamp< (d.unix_timestamp) and 
       d_prev.unix_timestamp< (d_inter.unix_timestamp) 

    WHERE 
     d_inter.unix_timestamp is null AND 
     (d_prev.current_state is null OR d_prev.current_state <> d.current_state 

) 

결과 :

line current_state unix_timestamp datetime 
1  1    1452639750 2016-01-13 00:02:30 
2  1    1452639750 2016-01-13 00:02:30 
2  0    1452640350 2016-01-13 00:12:30 
2  1    1452640650 2016-01-13 00:17:30 

나는 단지 current_state는 마찬가지로

0

을 변경 다음 행의 datetime에 열을 추가하고 싶습니다 나는 옳은 결과를 얻지 못했지만 도움이 될 수 있도록 여기에 내 스크래치를 남겼습니다. 내 기본적인 생각은 모든 변경 사항을 찾아 ID (change_num)를 할당하고 전환별로 그룹화하는 것입니다. 나중에 편집하겠습니다.

CREATE TABLE bde_production (
    `id`   INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
    `plant`  INT(3) UNSIGNED  NOT NULL, 
    `state`  TINYINT(1) UNSIGNED NOT NULL, 
    `unix_timest` INT(10) UNSIGNED NOT NULL, 
    `datetime` DATETIME   NOT NULL 
); 

INSERT INTO bde_production (plant, state, unix_timest, datetime) VALUES 
    (1, 1, 1452639750, "2016-01-13 00:02:30"), 
    (2, 1, 1452639750, "2016-01-13 00:02:30"), 
    (1, 1, 1452639900, "2016-01-13 00:05:00"), 
    (2, 1, 1452639900, "2016-01-13 00:05:00"), 
    (1, 1, 1452640050, "2016-01-13 00:07:30"), 
    (2, 1, 1452640050, "2016-01-13 00:07:30"), 
    (1, 1, 1452640200, "2016-01-13 00:10:00"), 
    (2, 1, 1452640200, "2016-01-13 00:10:00"), 
    (1, 1, 1452640350, "2016-01-13 00:12:30"), 
    (2, 0, 1452640350, "2016-01-13 00:12:30"), 
    (1, 1, 1452640500, "2016-01-13 00:15:00"), 
    (2, 0, 1452640500, "2016-01-13 00:15:00"), 
    (1, 1, 1452640650, "2016-01-13 00:17:30"), 
    (2, 1, 1452640650, "2016-01-13 00:17:30"), 
    (1, 1, 1452640800, "2016-01-13 00:20:00"), 
    (2, 1, 1452640800, "2016-01-13 00:20:00"); 


SET @line_num_a = 0; 
SET @line_num_b = 0; 
SET @change_num = 0; 

SELECT plant, 
    IFNULL(`changes_max_state`, `bde_max_state`) AS `current_state`, 
    `bde_min_date`, 
    IFNULL(`changes_max_date`, `bde_max_date`), 
    `changes_max_date`, 
    `bde_max_date` 
FROM (
     SELECT 
     bde.plant, 
     change_num, 
     MIN(bde.datetime) `bde_min_date`, 
     MAX(bde.datetime) `bde_max_date`, 
     MAX(bde.state) `bde_max_state`, 
     MIN(changes.datetime) `changes_min_date`, 
     MAX(changes.state) `changes_max_state`, 
     MAX(changes.datetime) `changes_max_date`-- MIN(bde.datetime), MAX(bde.datetime) 
     , MIN(changes.datetime_b), 
     MAX(changes.datetime_b) 
     FROM 
     bde_production bde LEFT JOIN (
             SELECT 
              # a.datetime is the max reading for plant in a.state 
              b.*, a.datetime AS datetime_b, @change_num := @change_num + 1 `change_num` 
             FROM 
              (
              SELECT 
               *, 
               @line_num_a := @line_num_a + 1 AS `line` 
              FROM (
                SELECT * 
                FROM bde_production 
                ORDER BY plant DESC 
               ) a1) a 
              JOIN (
               SELECT 
                *, 
                @line_num_b := @line_num_b + 1 AS `line` 
               FROM (
                 SELECT * 
                 FROM bde_production 
                 ORDER BY plant DESC 
                ) b1) b 
              ON 
               a.plant = b.plant AND a.line = b.line - 1 AND a.state <> b.state 
            ) changes 
      ON changes.plant=bde.plant AND bde.id > changes.id 
     GROUP BY change_num, plant 
    ) q 
; 
관련 문제