2014-10-17 2 views
0

Рев оператор не работает, но я не могу показаться, чтобы выяснить, почемуMySQL выберите AVG, ORDER BY, GROUP BY и LIMIT

select AVG(delay_in_seconds) from A_TABLE ORDER by created_at DESC GROUP BY row_type limit 1000; 

Я хочу, чтобы получить Avg-х самых последних 1000 строк для каждого ROW_TYPE , created_at имеет тип DATETIME, а row_type имеет тип VARCHAR

+0

RTFM: http://dev.mysql.com/doc/refman/5.0/en/select.html Заказ должен быть «select ... from ... где ... group ... order'. У вас порядок/группа отменена. –

ответ

0

Напишите ORDER BY в последнем сообщении.

SELECT AVG(delay_in_seconds) from A_TABLE GROUP BY row_type ORDER by created_at DESC limit 1000; 

прочитайте сайт mysql dev для получения более подробной информации.

+0

Получает ли этот запрос результат, удовлетворяющий спецификации OP? – spencer7593

2

Если вы хотите только 1000 самых последних строк, независимо от row_type, а затем получить среднее значение delay_in_seconds для каждого row_type, это довольно простой запрос. Например:

SELECT t.row_type 
    , AVG(t.delay_in_seconds) 
    FROM (
     SELECT r.row_type 
       , r.delay_in_seconds 
      FROM A_table r 
      ORDER BY r.created_at DESC 
      LIMIT 1000 
     ) t 
GROUP BY t.row_type 

Я подозреваю, однако, что этот запрос делает не удовлетворяют требованиям, которые были заданы. (Я знаю, что он не удовлетворяет тем, что я понял как спецификация.)

Если мы хотим, это среднее из последних 1000 строк для каждого row_type, это также было бы довольно просто ... если мы использовали базу данных, поддерживающую аналитические функции.

К сожалению, MySQL не обеспечивает поддержку аналитических функций. Но в MySQL можно эмулировать одно, но синтаксис немного задействован, и он зависит от поведения, которое не гарантировано.

В качестве примера:

SELECT s.row_type 
    , AVG(s.delay_in_seconds) 
    FROM ( 
     SELECT @row_ := IF(@prev_row_type = t.row_type, @row_ + 1, 1) AS row_ 
       , @prev_row_type := t.row_type AS row_type 
       , t.delay_in_seconds 
      FROM A_table t 
      CROSS 
      JOIN (SELECT @prev_row_type := NULL, @row_ := NULL) i 
      ORDER BY t.row_type DESC, t.created_at DESC 
     ) s 
WHERE s.row_ <= 1000 
GROUP 
    BY s.row_type 

ПРИМЕЧАНИЯ:

Рядный вид запроса будет затратным для больших наборов. То, что это эффективно, - это присвоение номера строки каждой строке. «Порядок по» сортирует строки в нисходящей последовательности на created_at, мы хотим, чтобы для последней строки было назначено значение 1, следующие последние 2 и т. Д. Эта нумерация строк будет повторяться для каждого отдельного значение row_type.

Для обеспечения производительности нам нужен подходящий индекс с ведущими столбцами (row_type,created_at,delay_seconds), чтобы избежать дорогостоящей операции «Использование файлового управления». Нам нужны по крайней мере те первые два столбца для этого, включая delay_seconds, который делает его индексом покрытия (запрос может быть полностью выполнен из индекса.)

Внешний запрос затем выполняется против набора результатов, возвращаемого из запроса вида (a «производная таблица»). Предикат в WHERE отфильтровывает все строки, которым присваивается номер строки, превышающий 1000, а остальная часть - GROUP BY GROUP BY и агрегат AVG.

Предложение LIMIT совершенно не нужно. Возможно, можно добавить некоторые дополнительные предикаты для некоторого дополнительного повышения производительности ... например, что, если мы указали самые последние 1000 строк, но только это были create_at за последние 30 или 90 дней?

(Я не совсем уверен, что это отвечает на вопрос, заданный ОП.То, что это отвечает: существует ли запрос, который может вернуть указанную ResultSet, используя AVG заполнителя и GROUP BY, ORDER BY и LIMIT статей)

нотабене. Этот запрос зависит от поведения пользовательских переменных MySQL, которые являются не гарантировано.


В приведенном выше вопросе показан один подход, но есть и другой подход. Можно использовать операцию «join» (из A_table с A_table), чтобы получить присвоенный номер строки (получая COUNT из числа строк, которые являются «более свежими», чем каждая строка. Однако с большими наборами, которые могут создавать если мы не будем его ограничивать.