SQL LIMIT动态N

时间:2019-01-25 15:04:48

标签: mysql sql group-by aggregate-functions

我想从所有具有指定County_number的站点获得(最后一行)平均气温。

因此,我的解决方案将是

SELECT AVG(air_temperature) 
  FROM weather 
 WHERE station_id IN (
       SELECT station_id 
         FROM stations 
        WHERE county_number = 25
       )
 ORDER 
    BY id DESC 
 LIMIT 1; 

很显然,这没有给出正确的行,因为它会基于一个站点曾经记录的所有空气温度返回平均空气温度。

回到问题所在,我想从每个具有指定County_number的站点获取最后插入的行的平均气温。

表天气

+------------------+-------------+------+-----+---------+----------------+
| Field            | Type        | Null | Key | Default | Extra          |
+------------------+-------------+------+-----+---------+----------------+
| id               | int(11)     | NO   | PRI | NULL    | auto_increment |
| station_id       | char(20)    | YES  | MUL | NULL    |                |
| timestamp        | timestamp   | YES  |     | NULL    |                |
| air_temperature  | float       | YES  |     | NULL    |                |
+------------------+-------------+------+-----+---------+----------------+

桌子台

+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| station_id    | char(20)    | NO   | PRI | NULL    |       |
| county_number | int(10)     | YES  |     | NULL    |       |
+---------------+-------------+------+-----+---------+-------+

表格已最小化

4 个答案:

答案 0 :(得分:0)

您可以通过计算station_id, max(timestamp)对并结合数据来查找最新的行:

SELECT AVG(air_temperature)
FROM (
    SELECT station_id, max(timestamp) AS timestamp
    FROM weather
    WHERE station_id IN (SELECT station_id FROM stations WHERE county_number = 25)
) AS a
JOIN weather AS w ON a.station_id = w.station_id AND a.timestamp = w.timestamp

答案 1 :(得分:0)

我建议使用join并进行一些过滤:

select avg(w.air_temperature)
from weather w join
     stations s
     on w.station_id = s.station_id
where s.county_number = 25 and
      w.timestamp = (select max(w2.timestamp) from weather w2 where w2.station_id = w.station_id)

答案 2 :(得分:0)

您可以通过检查max(timestamp)来获取最后插入的行:

SELECT 
  AVG(w.air_temperature) 
FROM weather w 
INNER JOIN (
  SELECT station_id, max(timestamp) maxtimestamp FROM weather GROUP BY station_id        
) t
ON w.station_id = t.station_id AND w.timestamp = t.maxtimestamp
WHERE 
  w.station_id IN (SELECT station_id FROM stations WHERE county_number = 25)

答案 3 :(得分:0)

更新:我刚刚注意到您的timestamp列可以为空,而您所说的是“最后插入的行”。那是ID最大的那个。因此:

从MySQL 8开始,您可以使用窗口函数以便只读取一次表:

select avg(air_temperature) 
from
(
  select air_temperature, id, max(id) over (partition by station_id) as max_id
  from weather 
  where station_id in (select station_id from stations where county_number = 25)
) analyzed
where id = max_id;

在旧版本中,您必须阅读两次表:

select avg(air_temperature) 
from weather 
where (station_id, id) in
(
  select station_id, max(id)
  from weather 
  where station_id in (select station_id from stations where county_number = 25)
  group by station_id
);