Выберите последние 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;
Я ищу запрос, извините, если мой вопрос был "настолько неправильным", что он толкнул вас всех в неправильном направлении. Я буду голосовать за ответы, которые помогли мне найти необходимый запрос.