Q:

Помогите составить SQL-запрос (извлечение первой и последней цены за период)

Дано: Есть таблица "trades", с полями: id, price, time. Каждую минуту в таблицу поступает 0..+бесконечность записей.
Извлечь: записи за последние 60 минут, где каждая запись будет содержать статистику за каждую минуту:

l - минимальная цена на промежутке
h - максимальная цена на промежутке
o - цена открытия (самая первая цена) 
c - цена закрытия (самая последняя цена)

(должно извлечься 60 записей)
Решение (неуд.):
SELECT
    MIN(price) AS l,
    MAX(price) AS h,
    (SELECT price FROM trades
        WHERE time BETWEEN (FLOOR(t.time/60) AND FLOOR(t.time/60)+59
        ORDER BY time ASC LIMIT 1) AS o,
    (SELECT price FROM trades
        WHERE time BETWEEN (FLOOR(t.time/60) AND FLOOR(t.time/60)+59
        ORDER BY time DESC LIMIT 1) AS c,
    time,
    FLOOR(time/60) AS minute
FROM trades t
WHERE time BETWEEN (UNIX_TIMESTAMP()-3600) AND UNIX_TIMESTAMP()
GROUP BY minute
ORDER BY minute ASC

Проблема в извлечении первой и последней цены за период. Для их извлечения использовались подзапросы. Данная конструкция вешает сервер MySQL.
Подскажите, пожалуйста, более удачное решение?

A:

Попробуйте так:
select mm.minute, 
  min(tmm.price) as min_price, max(tmm.price) as max_price,
  t_o.price as o_price, t_c.price as c_price
from
  (select min(id) as minid, max(id) as maxid, EXTRACT(DAY_MINUTE from time) as minute
    from trades
    group by EXTRACT(DAY_MINUTE from time)) as mm 
  join trades t_o on mm.minid = t_o.id
  join trades t_c on mm.maxid = t_c.id
  join trades tmm on EXTRACT(DAY_MINUTE from tmm.time)=mm.minute
group by mm.minute;

Предполагается, что id идут строго по возрастанию (если не так, то надо через time решать, но если там будут дубли все будет плохо).
EXTRACT тут используется для идентификации минуты, это может быть и любая другая функция, здесь год например не учитывается.
Фильтр по time between... добавите сами.

SQLFiddle

Есть еще вариант (более логичный): рассчитывать минуту для каждой записи при вставке, чтоб ее не считать каждый раз. Тогда EXTRACT(...) заменяется на эту колонку, повесить на нее индекс, будет гарантировано быстро.

