У меня есть приложение для мониторинга, которое хранит показатели в базе данных MySQL и использует RRDtool для рисования графиков временных рядов. Таблицы в БД имеют 3 столбца: временная метка, RRDKeyID и значение, т.е. есть таблица с данными, такие как:MySQL: выберите топ-10 и запишите другие
ts1 | user2 | some_value
ts1 | user4 | some_value
ts1 | user5 | some_value
ts1 | user7 | some_value
ts2 | user1 | some_value
ts2 | user2 | some_value
ts2 | user3 | some_value
ts2 | user5 | some_value
ts2 | user8 | some_value
ts3 | user3 | some_value
ts3 | user4 | some_value
ts3 | user5 | some_value
ts3 | user7 | some_value
...
Данные собраны в 1-минутными интервалами и пользователей (как вы их знаете) свободно подключаться к системе и генерировать метрики, так что в любой данный момент существует целый ряд пользователей в системе, которая ниже общей. Общее количество пользователей составляет около 1 тыс., И в сети их всегда бывает несколько сотен, что означает, что в таблице показателей есть несколько сотен строк с одинаковой меткой времени. Когда я создаю график, я не хочу показывать серию для каждого отдельного пользователя, потому что тогда график нечитабелен из-за слишком малого размера холста, ограниченной цветовой палитры, слишком длинной легенды и т. Д. Поэтому я вместо этого генерирую график, где только ТОП-10 пользователей по метрическим значениям отображаются индивидуально, а все остальные агрегируются в одну черную область. Вот как я это делаю:
Я получаю топ 10 из таблицы:
выбрать RRDKeyID, ср (значение) в качестве сред от metric_table где тс между 't1' и 't2' группа по RRDKeyID порядка они средний по алфавиту предел 10
Затем в Perl сгенерировать команду RRDtool, которая рисует график, где каждый пользователь (RRDKeyID) имеет собственный DEF, но только Defs пользователей из результатов SQL запросов нанесены непосредственно , все остальные Агрегатируется:
CDEF: другие = 0, user11, ADDNAN, user12, ADDNAN, user13, ADDNAN, ..., userN
, а затем "AREA: другие # 000000: ДРУГОЕ: СТЕК" отображается на графике.
Теперь я работаю над следующей версией приложения, где RRDtool будет заменен на D3.js из-за изменений в схеме БД, поэтому мне нужен другой способ генерации данных моих топ10 + других. Я не хочу отправлять необработанные данные клиенту и выполнять обработку на их стороне, потому что наборы данных могут быть очень большими, и обработка может занять много времени и процессор, поэтому я предпочел бы сделать это на стороне сервера. Я подозреваю, что это может быть возможным, чтобы получить результаты, которые я хочу в следующем формате:
ts | user | value
------+--------+-------
t1 | u1 | v
t1+1 | u1 | v
t1+2 | u1 | v
...
t2 | u1 | v
t1 | u2 | v
...
t2 | u2 | v
t1 | u3 | v
...
t2 | u3 | v
...
...
t1 | u10 | v
...
t2 | u10 | v
t1 | others | v
...
t2 | others | v
на одном дыхании (порядок не имеет значения), используя вложенный запрос, где есть подзапрос, который выбирает имена пользователей (RRDKeyIDs) и avg (значение) в течение заданного диапазона времени, а затем верхний запрос печатает результаты для имен пользователей, если они находятся в результатах подзапроса или иным образом добавляют их другим. Я не знаю, как выразить эту идею в SQL, поэтому я буду благодарен, если кто-то может предложить решение.
В шаге 1, вы не хотите 'ORDER BY avg (value) DESC'? –
@RickJames Конечно, мой плохой. Отредактировано. – mac13k