Reputation: 115
I have a table MeterReading in mysql and it has the following columns
meterid bigint(4),
reading bigint(4),
date date,
time time,
consumption,
primary key(meterid,reading)
i am inserting the vlues to this table except consumption and my problem is how to update the table based on these values.
i tried the following query
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));
i want the result like:
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 |
please help me
Upvotes: 0
Views: 720
Reputation: 79909
Try this instead:
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 ;
Update: Use IFNULL(g.MaxReading, 0) - a.reading
or you can use the ABS(IFNULL(g.MaxReading, 0) - a.reading)
.
Edit: So, you need to update each composite key (meterid
, reading
)'s consumption
value with the difference between the current reading value and the next row's reading value. If so you can do this:
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));
This will make your table meterreading
, after update, looks like:
| 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 |
Note that: I used the @rownum
variable to get each row's rank, and the thing is, this rank is based on the order of the Date
column, so it will get the next date's reading value.
Upvotes: 1