如何使用mysql计算2行之间的差异

时间:2013-01-03 09:54:33

标签: mysql

我在mysql中有一个表MeterReading,它有以下列

meterid bigint(4),
reading bigint(4),
date date,
time time,
consumption,
primary key(meterid,reading)

我正在向这个表插入除了消费之外的线索,我的问题是如何根据这些值更新表。

我尝试了以下查询

update MeterReading a 
set consumption=(select reading-IFNULL((select MAX(reading) from MeterReading  where meterid=a.meterid AND (date < a.date OR date = a.date AND time < a.time )),0));

我想要的结果如下:

  meterid | reading | date       | time     | consumption |
+---------+---------+------------+----------+-------------+
|       1 |     450 | 2012-10-05 | 06:05:05 |        450  |
|       1 |     550 | 2012-10-06 | 08:05:05 |        100  |
|       1 |     600 | 2012-10-07 | 09:05:05 |        50   |
|       1 |     700 | 2012-10-08 | 10:05:05 |        100  |

请帮帮我

1 个答案:

答案 0 :(得分:1)

改为尝试:

UPDATE MeterReading a 
LEFT JOIN
(
  SELECT meterid, MAX(reading) MaxReading
  FROM MeterReading
  GROUP BY meterid
) g ON g.meterid = a.meterid
SET a.consumption = IFNULL(g.MaxReading, 0) - a.reading ;

更新:使用IFNULL(g.MaxReading, 0) - a.reading或您可以使用ABS(IFNULL(g.MaxReading, 0) - a.reading)

SQL Fiddle Demo

<击>


修改:因此,您需要使用当前读数值之间的差异更新每个复合键(meteridreading)的consumption值和下一行的阅读价值。如果是这样,你可以这样做:

UPDATE MeterReading m
INNER JOIN
(
  SELECT 
    m.*,
    @rownum := @rownum + 1 AS rank
  FROM meterreading m, (SELECT @rownum := 0) r
  ORDER BY m.date 
) t1  ON m.meterid = t1.meterid 
     AND m.reading = t1.reading
LEFT JOIN 
(
  SELECT 
    m.*,
    @rownum2 := @rownum2 + 1 AS rank
  FROM meterreading m, (SELECT @rownum2 := 0) r
  ORDER BY m.date 
) t2  ON  t1.rank - t2.rank = 1
SET m.consumption = (t1.reading - IFNULL(t2.reading, 0));

Updated SQL Fiddle Demo

这将使您的表meterreading在更新后看起来像:

| METERID | READING |                           DATE |                           TIME | CONSUMPTION |
-----------------------------------------------------------------------------------------------------
|       1 |     450 | October, 05 2012 02:00:00+0000 | January, 01 1970 06:05:05+0000 |         450 |
|       1 |     550 | October, 06 2012 02:00:00+0000 | January, 01 1970 08:05:05+0000 |         100 |
|       1 |     600 | October, 07 2012 02:00:00+0000 | January, 01 1970 09:05:05+0000 |          50 |
|       1 |     700 | October, 08 2012 02:00:00+0000 | January, 01 1970 10:05:05+0000 |         100 |

请注意:我使用@rownum变量来获取每一行的排名,事实是,此排名基于Date列的顺序,因此它将获得下一个日期的阅读价值。