SQL LIMIT динамический N - PullRequest
0 голосов
/ 25 января 2019

Я хочу получить (в последнем ряду) среднюю температуру воздуха от всех станций с указанным номером страны.

Поэтому мое решение будет выглядеть примерно так:

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; 

Ясно, что это не дает правильную строку, поскольку возвращает среднюю температуру воздуха, основанную на всех значениях воздуха, когда-либо зарегистрированных на одной станции.

Возвращаясь к проблеме, я хочу получить среднюю температуру воздуха по последнему добавленному ряду для каждой станции с указанным номером страны.

Настольная погода

+------------------+-------------+------+-----+---------+----------------+
| 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    |       |
+---------------+-------------+------+-----+---------+-------+

Таблицы свернуты

Ответы [ 3 ]

0 голосов
/ 25 января 2019

Вы можете получить последнюю вставленную строку, проверив 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)
0 голосов
/ 25 января 2019

ОБНОВЛЕНИЕ: Я только что заметил, что ваш столбец timestamp обнуляется, а вы говорите о "последней вставленной строке". Это тот, у кого самый большой идентификатор. Следовательно:

Начиная с 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
);
0 голосов
/ 25 января 2019

Я бы порекомендовал сделать это с 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)
...