복붙노트

[SQL] MySQL은 - 이전 행, 그룹 별에서 값을 빼면

SQL

MySQL은 - 이전 행, 그룹 별에서 값을 빼면

나는 SN 번호로 이전에 소비 가치 기반을 가지고해야합니다. 이것은 내 데이터입니다 :

표 EnergyLog

SN     Date                 Value
2380   2012-10-30 00:15:51  21.01
2380   2012-10-31 00:31:03  22.04
2380   2012-11-01 00:16:02  22.65
2380   2012-11-02 00:15:32  23.11
20100  2012-10-30 00:15:38  35.21
20100  2012-10-31 00:15:48  37.07
20100  2012-11-01 00:15:49  38.17
20100  2012-11-02 00:15:19  38.97
20103  2012-10-30 10:27:34  57.98
20103  2012-10-31 12:24:42  60.83

이 결과 I 필요하다 :

SN      Date                 Value  consumption
2380    2012-10-30 00:15:51  21.01  0
2380    2012-10-31 00:31:03  22.04  1.03
2380    2012-11-01 00:16:02  22.65  0.61
2380    2012-11-02 00:15:32  23.11  0.46
20100   2012-10-30 00:15:38  35.21  0
20100   2012-10-31 00:15:48  37.07  1.86
20100   2012-11-01 00:15:49  38.17  1.1
20100   2012-11-02 00:15:19  38.97  0.8
20103   2012-10-30 10:27:34  57.98  0
20103   2012-10-31 12:24:42  60.83  2.85

해결법

  1. ==============================

    1.MySQL의 변수로 작업하는 것은, 그와 같은 인라인 프로그램 변수 할당 중대하다. 첫째, FROM 절 공백을 디폴트, 당신을 위해 @ 변수 "를 선언합니다." 그런 다음 당신이 그들을 원하는 기대 순서로 레코드를 쿼리합니다. 그것은 통해 데이터 대신 시간 집약적 일 수 반복 부질 통한 단일 패스한다.

    MySQL의 변수로 작업하는 것은, 그와 같은 인라인 프로그램 변수 할당 중대하다. 첫째, FROM 절 공백을 디폴트, 당신을 위해 @ 변수 "를 선언합니다." 그런 다음 당신이 그들을 원하는 기대 순서로 레코드를 쿼리합니다. 그것은 통해 데이터 대신 시간 집약적 일 수 반복 부질 통한 단일 패스한다.

    각 행 읽기를 들어, 현재 레코드의 SN과 @lastSN을 비교합니다. 이 같은 경우와 달리 항상 0을 반환하면, 단순한 차이를 계산한다. 후에 만 수행 비교가의 @lastSN 및 @lastValue 다음 기록 비교를 위해 현재 레코드의와 동일하게 설정.

    select
          EL.SN,
          EL.Date,
          EL.Value, --remove duplicate alias
          if( @lastSN = EL.SN, EL.Value - @lastValue, 0000.00 ) as Consumption,
          @lastSN := EL.SN,
          @lastValue := EL.Value
       from
          EnergyLog EL,
          ( select @lastSN := 0,
                   @lastValue := 0 ) SQLVars
       order by
          EL.SN,
          EL.Date
    
  2. ==============================

    2.이 트릭을 수행해야합니다

    이 트릭을 수행해야합니다

    SELECT l.sn,
           l.date, 
           l.value,
           l.value - (SELECT value 
                      FROM energylog x
                      WHERE x.date < l.date
                      AND x.sn = l.sn
                      ORDER BY date DESC
                      LIMIT 1) consumption
    FROM energylog l;
    

    참조 SQLFiddle : http://sqlfiddle.com/#!2/b9eb1/8

  3. ==============================

    3.거의 보편적 인 해결책은 조인 조건에 상관 하위 쿼리를 포함하여, 이전 기록을 찾기 위해, 자체의 데이터를 결합하는 것입니다 ...

    거의 보편적 인 해결책은 조인 조건에 상관 하위 쿼리를 포함하여, 이전 기록을 찾기 위해, 자체의 데이터를 결합하는 것입니다 ...

    SELECT
      ThisLog.*,
      COALESCE(ThisLog.Value - PrevLog.Value, 0) AS consumption
    FROM
      EnergyLog    AS ThisLog
    LEFT JOIN
      EnergyLog    AS PrevLog
        ON  PrevLog.SN   = ThisLog.SN
        AND PrevLog.Date = (SELECT MAX(Date)
                              FROM EnergyLog
                             WHERE SN   = ThisLog.SN
                               AND Date < ThisLog.Date)
    

    모두 (SN, 날짜)를 포함하는 하나 개의 인덱스와 최선이 수행한다.

  4. ==============================

    4.이 같은 동일한 테이블의 두 행에 가입 할 수 있습니다 :

    이 같은 동일한 테이블의 두 행에 가입 할 수 있습니다 :

        SELECT this.*, prev.*
          FROM tbl this
    INNER JOIN tbl prev ON prev.id =
               ( 
                   SELECT max(t.id) 
                   FROM tbl t  
                   WHERE t.id < this.id
               )     
         WHERE ...
    

    귀하의 경우처럼 보일 것입니다 그래서 :

        SELECT this.SN, this.Date, this.Value, (this.Value - prev.Value) AS consumption
          FROM EnergyLog this
    INNER JOIN EnergyLog prev ON prev.Date =
               ( 
                   SELECT max(t.Date) 
                   FROM EnergyLog t  
                   WHERE t.Date < this.Date
               )     
    
  5. ==============================

    5.한 번 쿼리 아래를보십시오 할 수 있습니다.

    한 번 쿼리 아래를보십시오 할 수 있습니다.

    SELECT e1.*,
       (SELECT Value
        FROM EnergyLog e2
        WHERE e2.sn = e1.sn AND e2.date < e1.date
        ORDER BY date DESC
        LIMIT 1)-l.Value consumption
    FROM EnergyLog e1;
    
  6. from https://stackoverflow.com/questions/13196190/mysql-subtracting-value-from-previous-row-group-by by cc-by-sa and MIT license