I have a SQL Table where the absolute value of an energy meter (counter) is logged. New rows are added automatically every increase of 5 of value or at the latest every 15 minutes.
The table data could look something like this:
id value time
1 2500 21.12.16 01:09:52
2 2505 21.12.16 01:10:23
3 2510 21.12.16 01:11:00
4 2512 21.12.16 01:26:00
...
1500 4502 22.12.16 00:00:03
1501 4507 22.12.16 00:00:58
...
3456 6528 23.12.16 00:00:10
3457 6533 23.12.16 00:05:22
Given a start time, end time and sampling time, is it possible to get the difference between values?
For example,
start_time = 21.12.16 02:00:00
stop_time = 21.12.16 03:15:00
sampling_time = 15 minutes
Should do the following:
Get value at start_time (or closest to it) = value1
Get value at start_time + sampling_time (or closest to it) = value2
Select difference between value1 and value 2
Get value at start_time + 2*sampling_time (or closest to it) = value3
Select difference between value 2 and value 3
... so on, until start_time + n*sampling_time > stop_time
Expected result could be something like this:
20 //Difference between value 1 at 2:00 (or closest) and value 2 at 2:15 (or closest)
18 //Diff. between value 2 (2:15) and value 3 (2:30)...
23
15
45 //... Diff. between value n-1 (3:00) and value n (3:15)
Is this with pure SQL possible? Or should I log the consumed energy on a different way?
I began by creating the table and inserting the first few rows to make, so that you will have an understanding of the table schema I'm using. Notice that the id
is considered as PRIMARY KEY
value.
CREATE table t1(
`id` int PRIMARY KEY,
`value` int,
`time` timestamp
)Engine=InnoDB;
INSERT INTO t1 VALUES
(1,2500,'21.12.16 01:09:52'),
(2,2505,'21.12.16 01:10:23'),
(3,2510,'21.12.16 01:11:00'),
(4,2512,'21.12.16 01:26:00');
The query you are asking for is a subtraction between 2 different queries:
Query 1: select value from t1 where time = **smaller_timestamp**
Query 2: select value from t1 where time = **larger_timestamp**
To Get the result: SELECT query1 - query2
;
Example:
-- smaller timestamp
mysql> select value from t1 where time ='21.12.16 01:09:52';
+-------+
| value |
+-------+
| 2500 |
+-------+
1 row in set (0.00 sec)
-- larger timestamp
mysql> select value from t1 where time ='21.12.16 01:26:00';
+-------+
| value |
+-------+
| 2512 |
+-------+
1 row in set (0.00 sec)
mysql> SELECT (select value from t1 where time ='21.12.16 01:26:00')-(select value from t1 where time ='21.12.16 01:09:52') AS value_difference;
+------------------+
| value_difference |
+------------------+
| 12 |
+------------------+
1 row in set (0.00 sec)
More generically you can use methods like DATE_ADD(date, INTERVAL)
utilize different start/end times.
Example: For this case i used time='21.12.16 01:11:00' and INTERVAL=15 minutes.
mysql> SELECT
-> (select value from t1 where time =DATE_ADD('21.12.16 01:11:00', INTERVAL 15 minute))-
-> (select value from t1 where time='21.12.16 01:11:00')
-> AS
-> value_difference;
+------------------+
| value_difference |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
I should let you know that if you want to do "closest to", then rather than using "=" you should use greater/less than comparison, ORDER BY
, and the function LIMIT
rather than just a select.
Example:
mysql> SELECT
-> (select value from t1 where time<=DATE_ADD('21.12.16 01:11:00', INTERVAL 15 minute) ORDER BY value DESC LIMIT 1)-
-> (select value from t1 where time<='21.12.16 01:09:52' ORDER by value ASC LIMIT 1)
-> AS
-> value_difference;
+------------------+
| value_difference |
+------------------+
| 12 |
+------------------+
1 row in set (0.00 sec)
Per the request of @bishop, the following is an example of these queries as a stored procedure.
The first case is when there are 2 timestamps to compare from:
DELIMITER //
CREATE PROCEDURE calculateValue(startTime TIMESTAMP, endTime TIMESTAMP)
BEGIN
set @startTime = startTime;
set @endTime = endTime;
set @resultStart=concat("SELECT value FROM t1 WHERE time <='",@startTime,"' ORDER BY value DESC LIMIT 1");
set @resultEnd=concat("SELECT value FROM t1 WHERE time <= '",@endTIME,"' ORDER BY value DESC LIMIT 1");
set @query=concat("SELECT (",@resultEnd,")-(",@resultStart,") AS 'value_difference'");
prepare stmt from @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
The second case is when using the DATE_ADD
function.
DELIMITER //
CREATE PROCEDURE calculateValue(startTime TIMESTAMP, timeInterval VARCHAR)
BEGIN
set @startTime = startTime;
set @timeInterval= timeInterval;
set @resultStart=concat("SELECT value FROM t1 WHERE time <=DATE_ADD('",@startTime,"',INTERVAL ",@timeInterval,") ORDER BY value DESC LIMIT 1");
set @resultEnd=concat("SELECT value FROM t1 WHERE time <= '",@endTIME,"' ORDER BY value DESC LIMIT 1");
set @query=concat("SELECT (",@resultEnd,")-(",@resultStart,") AS 'value_difference'");
prepare stmt from @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.