简体   繁体   中英

MySQL select rate of change on energy counter given sampling time

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM