Daniel
Daniel

Reputation: 21

MySQL: Select corresponding row for maximum value grouped by date

I have a table with hourly temperatures:

id   timestamp   temperature

I want to select the highest temperature AND the corresponding timestamp for each day.

select max(temperature), timestamp from table group by date(from_unixtime(timestamp))

does not work because it always returns the timestamp of the first row (but I need the timestamp from the row with the highest temperature).

Any suggestions would be greatly appreciated.

Upvotes: 1

Views: 1894

Answers (3)

Chris Strickland
Chris Strickland

Reputation: 3490

Select the max temperature for each date, and then put that inside a join back to the table on the temperature and date, which will allow you to select the rows that match for temperature and date. A join will be faster than a subquery in most situations, and you can't always group inside a subquery, anyway.

Use date() to get the date part from the timestamp, and from_unixtime() will get a mySQL timestamp from a unix timestamp stored as either a string or an integer.

SELECT temperature, timestamp 
FROM temp t
JOIN (
    SELECT  date(from_unixtime(timestamp)) as dt, 
            max(temperature) as maxTemp
    FROM temp 
    GROUP BY date(from_unixtime(timestamp))
) m ON (
    t.temperature = m.maxTemp AND
    date(from_unixtime(t.timestamp)) = m.dt
)

However, I would suggest changing the table to store the timestamp as timestamp instead of varchar or int, and doing the conversion once when the data is inserted, instead of having to put it throughout the query. It will make things easier to read and maintain in the long term. Here's the same query if you change timestamp to be an actual timestamp:

SELECT temperature, timestamp 
FROM temp t
JOIN (
    SELECT  date(timestamp) as dt, 
            max(temperature) as maxTemp
    FROM temp 
    GROUP BY date(timestamp)
) m ON (
    t.temperature = m.maxTemp AND
    date(t.timestamp) = m.dt
)

Just a little easier to read, and probably faster, depending on how much data you have. You could also write that with an implicit join, which might be easier to read still. Just depends on your taste.

SELECT temperature, timestamp 
FROM temp t, (
    SELECT  date(timestamp) as dt, 
            max(temperature) as maxTemp
    FROM temp 
    GROUP BY date(timestamp)
) m 
WHERE t.temperature = m.maxTemp
AND date(t.timestamp) = m.dt

Upvotes: 1

PodTech.io
PodTech.io

Reputation: 5254

Use a sub query like this;

select  * from temp WHERE temperature=(select min(temperature) from temp)

Upvotes: 1

Ganesh Rengarajan
Ganesh Rengarajan

Reputation: 2006

Try this one....

select max(temperature), timestamp from temp group by UNIX_TIMESTAMP(date(timestamp));

Upvotes: 1

Related Questions