简体   繁体   中英

mysql : Get latest value and sum of values from previous hour

I would like to return a product together with its latest value and values from last hour.

I have a product-table :

id, name, type (and so on)...

I have a values-table :

id_prod, timestamp, value

Something like :

12:00:00 = 10
12:15:00 = 10
12:30:00 = 10
12:45:00 = 10
13:00:00 = 10
13:15:00 = 10
13:30:00 = 10

I would like a query that returns the latest value (13:30:00) together with the sum of values one hour back. This should return:

time = 13:30:00
latestread = 10
lasthour = 40

What I almost got working was:

SELECT *,
(SELECT value FROM values S WHERE id_prod=P.id 
ORDER BY timestamp DESC LIMIT 1) as latestread,
(SELECT sum(value) FROM values WHERE id_prod=D.id and 
date_created>SUBTIME(S.date_created,'01:00:00')) as trendread 
FROM prod P ORDER BY name

But this fails with "Unknown column 'S.date_created' in 'where clause'"

Any suggestions?

If I understand correctly what you're trying to do, then You would have something like:

SELECT p.id, max(date_created), sum(value), mv.max_value
FROM product p
JOIN values v on p.id = v.product_id
JOIN (SELECT product_id, value as max_value
      FROM values v2
      WHERE date_created = (SELECT max(date_created) FROM values WHERE product_id=v2.product_id)) mv on product_id=p.id
WHERE date_created between DATE_SUB(now(), INTERVAL 1 HOUR)) and now()
GROUP BY p.id
ORDER BY p.id

Aleks G and mhasan gave solutions, but not the reason why this fails. The reason this fails is because the alias S is not known inside the subquery. Subqueries have no knowledge about the tables outside their scope.

You have missed providing alias for table Values in subquery below

SELECT *,
(SELECT value FROM values S WHERE id_prod=P.id 
ORDER BY timestamp DESC LIMIT 1) as latestread,
(SELECT sum(value) FROM values S WHERE id_prod=P.id and 
date_created>SUBTIME(S.date_created,'01:00:00')) as trendread 
FROM prod P ORDER BY name

I think this is the query that you are trying to write:

SELECT p.*,
      (SELECT v.value
       FROM values v
       WHERE v.id_prod = p.id 
       ORDER BY v.timestamp DESC
       LIMIT 1
      ) as latestread,
      (SELECT sum(v.value)
       FROM values v
       WHERE v.id_prod = p.id and 
             v.timestamp > SUBTIME(now(), '01:00:00')
     ) as trendread 
FROM prod p
ORDER BY p.name;

This changes all the aliases to be abbreviations for the table name. It also fixes the expression for the last hour by using now() and gets rid of date_created which doesn't seem to be in either table based on the question. The query conveniently assumes that timestamp is a datetime . If it is a unix timestamp, then somewhat different time logic is necessary.

This should be reasonably efficient with an index on values(id_prod, timestamp, value) .

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