Я хочу создать отчет о временной шкале, который показывает, для каждой даты на временной шкале перемещение среднее из последних N точек данных в наборе данных, которое имеет некоторые меры и даты, которые они измеряли. У меня есть таблица календаря, заполненная каждый день, чтобы указать даты. Я могу рассчитать график, чтобы показать общий среднего до этой даты довольно просто с корреляцией подзапросом (реальная ситуация гораздо сложнее, чем это, но она по существу может быть упрощена до этого):Как вычислить скользящее среднее в MySQL в коррелированном подзапросе?
SELECT c.date
, ( SELECT AVERAGE(m.value)
FROM measures as m
WHERE m.measured_on_dt <= c.date
) as `average_to_date`
FROM calendar c
WHERE c.date between date1 AND date2 -- graph boundaries
ORDER BY c.date ASC
Я читал об этом несколько дней, и я не нашел хороших решений. Некоторые предположили, что LIMIT может работать в подзапросе (LIMIT поддерживается в подзапросах текущей версии MySQL), однако LIMIT применяется к набору возвращаемых значений, а не к строкам, входящим в совокупность, поэтому не имеет значения, добавить их.
Я также могу написать неагрегированный SELECT с LIMIT и затем скомпилировать его, потому что коррелированный подзапрос не допускается внутри оператора FROM. Так что это (к сожалению) не будет работать:
SELECT c.date
, SELECT AVERAGE(last_5.value)
FROM ( SELECT m.value
FROM measures as m
WHERE m.measured_on_dt <= c.date
ORDER BY m.measured_on_dt DESC
LIMIT 5
) as `last_5`
FROM calendar c
WHERE c.date between date1 AND date2 -- graph boundaries
ORDER BY c.date ASC
Я думаю, мне нужно, чтобы избежать подзапрос подход полностью и посмотреть, если я делаю это с умным присоединиться/строка нумерации метод с пользовательскими переменными, а затем агрегатных что, но пока я работаю над этим, я думал, что спрошу, знает ли кто-нибудь лучший метод?
UPDATE: Хорошо, у меня есть решение, которое я упростил для этого примера. Он полагается на некоторую обманчивость пользовательской переменной, чтобы количественно измерять показатели с календарной даты. Он также выполняет кросс-продукт с таблицей календаря (вместо подзапроса), но у этого есть неудачный побочный эффект, связанный с тем, что трюк с нумерацией строк терпит неудачу (пользовательские переменные оцениваются, когда они отправляются клиенту, а не когда строка оценивается), поэтому для обхода этого я должен был вложить запрос на один уровень, заказать результаты, а затем применить трюк нумерации строк к этому набору, который затем работает.
Этот запрос возвращает только даты календаря, для которых существуют меры, поэтому, если вы хотите, чтобы вся временная шкала вы просто выбирали календарь и LEFT JOIN для этого набора результатов.
set @day = 0;
set @num = 0;
set @LIMIT = 5;
SELECT date
, AVG(value) as recent_N_AVG
FROM
( SELECT *
, @num := if(@day = c.date, @num + 1, 1) as day_row_number
, @day := day as dummy
FROM
(SELECT c.full_date
, m.value
, m.measured_on_dt
FROM calendar c
JOIN measures as m
WHERE m.measured_on_dt <= c.full_date
AND c.full_date BETWEEN date1 AND date2
ORDER BY c.full_date ASC, measured_on_dt DESC
) as full_data
) as numbered
WHERE day_row_number <= @LIMIT
GROUP BY date
Строка нумерация трюк может быть обобщен на более сложные данные (мои меры в нескольких измерениях, которые нуждаются в агрегировании вверх).
Итак, ваше решение саморешено, или вы все еще застряли на чем-то, и если да, то что это такое. Предоставление некоторых выборочных данных тоже помогло бы ... – DRapp
Я разрешил это, но это взломать. Это должна быть общая проблема, поэтому мне интересно, есть ли лучшее решение. – Gruff
На самом деле это не хак, если вам нужно определенное количество на каждую кандидатуру. переменные sql идеально подходят для такого типа обработки. – DRapp