How to find last value increase in a groupped MySQL table?

witkacy26 :

I'm doing some coronavirus statistics. Would you help me with a query, please. I'd like to get the LAST infected ('confirmed' field) growth for each country. Some countries doesn't update every day, so it needs to be a difference between second last meassure and the last one for each country.

In short - how to find last value increase in a groupped table?

The table looks like this:

CREATE TABLE coronavirus ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, place VARCHAR(30), province VARCHAR(30), country VARCHAR(40), updated TIMESTAMP, confirmed INTEGER, deaths INTEGER, recovered INTEGER, latitude FLOAT, longitude FLOAT);

Thanks!

PS. The table contents looks like this:

mysql> select * from coronavirus where id>8000 order by id limit 10;
+------+-------+-----------------+-------------+---------------------+-----------+--------+-----------+----------+-----------+
| id   | place | province        | country     | updated             | confirmed | deaths | recovered | latitude | longitude |
+------+-------+-----------------+-------------+---------------------+-----------+--------+-----------+----------+-----------+
| 8001 | NULL  | Shanghai        | China       | 2020-03-23 14:18:01 |       404 |      4 |       329 |   31.202 |   121.449 |
| 8002 | NULL  | Shanxi          | China       | 2020-03-13 08:56:40 |       133 |      0 |       133 |  37.5777 |   112.292 |
| 8003 | NULL  | Sichuan         | China       | 2020-03-22 07:20:38 |       543 |      3 |       536 |  30.6171 |    102.71 |
| 8004 | NULL  | Sint Maarten    | Netherlands | 2020-03-23 23:19:21 |         2 |      0 |         0 |  18.0425 |  -63.0548 |
| 8005 | NULL  | South Australia | Australia   | 2020-03-23 23:23:20 |       134 |      0 |         6 | -34.9285 |   138.601 |
| 8006 | NULL  | St Martin       | France      | 2020-03-23 23:19:21 |         8 |      0 |         0 |  18.0708 |  -63.0501 |
| 8007 | NULL  | Tasmania        | Australia   | 2020-03-23 23:23:20 |        28 |      0 |         3 | -42.8821 |   147.327 |
| 8008 | NULL  | Tianjin         | China       | 2020-03-23 03:57:57 |       141 |      3 |       133 |  39.3054 |   117.323 |
| 8009 | NULL  | Tibet           | China       | 2020-02-23 11:19:02 |         1 |      0 |         1 |  31.6927 |   88.0924 |
| 8010 | NULL  | Victoria        | Australia   | 2020-03-23 23:23:20 |       355 |      0 |        97 | -37.8136 |   144.963 |
+------+-------+-----------------+-------------+---------------------+-----------+--------+-----------+----------+-----------+

mysql> select count(*) from coronavirus;                                                                                                                           +----------+
+----------+
| count(*) |
+----------+
|    34783 |
+----------+
Tum :

This shows the latest entry + the increase from the previous entry:

SELECT
    cv.country,
    cv.confirmed,
    (cv.confirmed - (
            SELECT
                confirmed
            FROM
                coronavirus
            WHERE
                country = cv.country
                AND id != cv.id
            ORDER BY
                updated DESC
            LIMIT 1)) AS confirmed_increase
FROM
    coronavirus cv
    INNER JOIN (
        SELECT
            MAX(updated) AS updated,
            country
        FROM
            coronavirus
        GROUP BY
            country) cv2 ON cv2.country = cv.country
    AND cv.updated = cv2.updated
WHERE
    cv.updated = cv2.updated;

What this does: As GROUP BY goes before ORDER BY we need to work around this first, so it fetches all entries and does a JOIN on itself to only fetch the latest entries for all countries. Then it uses a subquery to find the latest item of the same country which IS NOT the same ID as the latest entry, so that will be the forelast entry. Note that if you have other conditions for your query they need to be added to the subquery as well.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=401706&siteId=1