Выберите последние 30 пунктов в группе по - PullRequest
1 голос
/ 24 сентября 2011

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

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

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) имеет много измерений, по одному на день секунду .Теперь я хочу выбрать температуру каждой станции за последние 30 дней измерений , где у станции есть как минимум 30 измерений температуры.

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

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

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

Ответы [ 3 ]

2 голосов
/ 24 сентября 2011

Это запрос, который должен выбрать 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

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

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

2 голосов
/ 24 сентября 2011
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
0 голосов
/ 25 сентября 2011
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;

Это запрос, который я искал, извините, если мой вопрос был «настолько неправильным», что он подтолкнул вас всех в неправильном направлении.Я буду голосовать за ответы, которые помогли мне найти нужный запрос.

...