I am trying to write some sql code to embed in Qt to find out when it last rained. Table
CREATE TABLE `weather_data` (
`time` bigint(20) NOT NULL,
`temp_1` float DEFAULT NULL,
`humid_1` float DEFAULT NULL,
`wind_avg` float DEFAULT NULL,
`wind_max` float DEFAULT NULL,
`wind_dir` smallint(6) DEFAULT NULL,
`rain_raw` float DEFAULT NULL,
`pressure` float DEFAULT NULL,
`temp_2` float DEFAULT NULL,
`humid_2` float DEFAULT NULL,
`temp_3` float DEFAULT NULL,
`humid_3` float DEFAULT NULL,
`temp_4` float DEFAULT NULL,
`humid_4` float DEFAULT NULL,
`temp_5` float DEFAULT NULL,
PRIMARY KEY (`time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
I have some code that finds the last entry in my table that returns a time stamp and the current rain total:
MariaDB [weatherV2_db]> SELECT time,rain_raw FROM weather_data ORDER BY time DESC LIMIT 1;
+------------+----------+
| time | rain_raw |
+------------+----------+
| 1755075032 | 23.6529 |
+------------+----------+
1 row in set (0.000 sec)
I am now looking for an efficient way to search backwards in the table to find when the "rain_raw" value changes and return the associated "time" value. My current method uses a simple "top down(?)" search which is eating Mb's of bandwith to my remote mariadb server. This method also shows up as "the" major use of cpu cycles when I profile my application. The database is ordered by the "time" field and the "time" field values are unique.
Any help would be appreciated.
Typical table
...
| 1754642997 | 23.6409 |
| 1754643045 | 23.6409 |
| 1754643093 | 23.6409 |
| 1754643141 | 23.6409 |
| 1754643189 | 23.6409 |
| 1754643237 | 23.6409 |
| 1754643285 | 23.6409 |
| 1754643333 | 23.6409 |
| 1754643381 | 23.6409 |
| 1754643429 | 23.6409 |
| 1754643477 | 23.6529 | <------ I want this time stamp
| 1754643525 | 23.6529 |
| 1754643573 | 23.6529 |
| 1754643621 | 23.6529 |
| 1754643669 | 23.6529 |
...
My current solution is to run the following query with an incrementing value for i until the value of rain_raw changes from the current last value in the table :
QString query=QString().asprintf("SELECT time,rain_raw FROM weather_data ORDER BY time DESC LIMIT 1 OFFSET %d",i);
The remote mariadb server is:
mysql Ver 15.1 Distrib 10.6.7-MariaDB, for Linux (x86_64) using readline 5.1
The time stamps are seconds from the epoch.
Using the suggested solution:
SELECT time, rain_raw FROM (SELECT time, rain_raw, LAG(rain_raw) OVER (ORDER BY time) AS lag_rain_raw FROM weather_data) t WHERE rain_raw <> lag_rain_raw;
Gives me :
...
| 1754581175 | 23.5469 |
| 1754581319 | 23.5469 |
| 1754581367 | 23.5589 |
| 1754581463 | 23.5589 |
| 1754582039 | 23.5699 |
| 1754582663 | 23.5939 |
| 1754582759 | 23.6059 |
| 1754582855 | 23.6179 |
| 1754582951 | 23.6289 |
| 1754583383 | 23.6409 |
| 1754643477 | 23.6529 | <---- Required answer.
| 1754643525 | 23.6529 |
+------------+----------+
4094 rows in set (1.240 sec)
The last entry is the current last row in the table. The row above that is the value I am looking for. The rest appear to be all the other rain transition markers. Thanks but I expected to just get the last rain transition not all of them.
On a second look the last entry from the result is not the end of the table could it be a floating point error ?
The solution supplied answers my question. Thank you.
SELECT time, rain_raw FROM (SELECT time, rain_raw, LAG(rain_raw) OVER (ORDER BY time) AS lag_rain_raw FROM weather_data) t WHERE ROUND(rain_raw,3) <> ROUND(lag_rain_raw,3) ORDER BY time DESC LIMIT 1;