我在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 |
请帮帮我
答案 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)
。
<击> 撞击>
修改:因此,您需要使用当前读数值之间的差异更新每个复合键(meterid
,reading
)的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));
这将使您的表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
列的顺序,因此它将获得下一个日期的阅读价值。