Выберите последние 30 элементов на группу

Надеюсь, что название имеет смысл.

В этом примере у меня будет следующая таблица в моей базе данных

measurements
==================================
stn | date        | temp | time  =
1   | 01-12-2001  | 2.0  | 14:30 =
1   | 01-12-2001  | 2.1  | 14:31 =
1   | 03-12-2001  | 1.9  | 21:34 =
2   | 01-12-2001  | 4.5  | 12:48 =
2   | 01-12-2001  | 4.7  | 12:49 =
2   | 03-12-2001  | 4.9  | 11:01 =
==================================

И так далее и т.д.

Каждая станция (stn) имеет много измерений, по одному в day second. Теперь я хочу выбрать температуру каждой станции из последних 30 days измерений, где станция имеет не менее 30 измерений температуры.

Я играл с подзапросами и группами, но я не могу понять это.

Надеюсь, кто-то может помочь мне здесь.

отредактировал таблицу Мой пример был упрощен, оставив критический фрагмент информации. Пожалуйста, просмотрите вопрос.

Ответы

Ответ 1

select t1.stn,t1.date,t1.temp,t1.rn from (
select *,
   @num := if(@stn = stn, @num + 1, 1) as rn,
   @stn := stn as id_stn
from table,(select @stn := 0, @num := 1) as r
order by stn asc, date desc) as t1
inner join (select `stn`
           from table
          where concat_ws(' ',date,time) >= now() - interval 30 day
          group by `stn`
         having count(*) >= 30) as t
on t1.stn = t.stn
and t1.rn <= 30
order by stn,date desc,time desc

Ответ 2

Это запрос, который должен выбрать Last 30 entries where there are at least 30 entries for a station

Этот запрос основан на ответе здесь nick rulez, поэтому, пожалуйста, поддержите его

SELECT t1.stn, t1.date, t1.temp, t1.time FROM 
    (
        SELECT *,
            @num := if(@stn = stn, @num + 1, 1) as rn,
            @stn := stn as id_stn
        FROM 
            `tablename`, 
            (SELECT @stn := 0, @num := 1) as r
        ORDER BY stn asc, date desc
    ) as t1
INNER JOIN 
    (
        SELECT `stn`
        FROM `tablename` 
        GROUP BY `stn`
        HAVING COUNT(*) >= 30
    ) as t
ON t1.stn = t.stn
AND t1.rn <= 30
ORDER BY stn, date desc, time desc

Я тестировал его на базе данных, созданной мной на основе вашей схемы, и отлично работает.

Чтобы узнать больше о таких запросах, посмотрите здесь Квоты внутри группы (Top N на группу)

Ответ 3

SELECT stn, date, temp FROM
(
SELECT stn, date, temp, @a:=IF(@lastStn=stn, @a+1, 1) countPerStn, @lastStn:=stn 
FROM cache 
GROUP BY stn, date
ORDER BY stn, date DESC
) as tempTable 
WHERE countPerStn > 30;

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