简体   繁体   English

MySQL:选择对应的行以按日期分组最大值

[英]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. 任何建议将不胜感激。

试试这个...

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

使用这样的子查询;

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

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. 使用date()从时间戳获取日期部分, from_unixtime()将从存储为字符串或整数的unix时间戳获取mySQL timestamp

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. 但是,我建议更改表以将时间timestamp存储为timestamp而不是varcharint ,并在插入数据时进行一次转换,而不必在整个查询过程中进行转换。 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 : 如果将时间戳记更改为实际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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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