Mail.ruПочтаМой МирОдноклассникиИгрыЗнакомстваНовостиПоискСмотриComboВсе проекты

Нестандартное извлечение данных из БД

Яки Бакич Мастер (2108), закрыт 10 месяцев назад
На самом деле не знал как точно тему озаглавить.
Суть такая. В одной таблице у меня смешано три типа данных: температура, давление, влажность. Их значения находятся в столбце value. Есть столб parameter, в котором указано - что это - t, p или h. Мне надо считать эти данные и вывести на dashboard одним запросом.
Уточню:
Данные поступают раз в минуту с 15 приборов. В каждом приборе три сенсора: давление, влажность, температура. То есть раз в минуту база пополняется на 45 строк. Мне нужно считать данные за последнюю минуту, выбрать мин, макс и сред для каждого из показателей и отобразить на панели. Проблема в том, что это должен быть 1 запрос.

Есть варианты?
Лучший ответ
Андрей Искусственный Интеллект (149634) 10 месяцев назад
Например, так:

SELECT
MIN(IF(parameter = 't', value, NULL)) AS t_min,
MAX(IF(parameter = 't', value, NULL)) AS t_max,
AVG(IF(parameter = 't', value, NULL)) AS t_avg,
MIN(IF(parameter = 'p', value, NULL)) AS p_min,
MAX(IF(parameter = 'p', value, NULL)) AS p_max,
AVG(IF(parameter = 'p', value, NULL)) AS p_avg,
MIN(IF(parameter = 'h', value, NULL)) AS h_min,
MAX(IF(parameter = 'h', value, NULL)) AS h_max,
AVG(IF(parameter = 'h', value, NULL)) AS h_avg
FROM info
WHERE dt_created > NOW() - INTERVAL 1 MINUTE;

Или так:

SELECT * FROM
(SELECT MIN(value) AS t_min, MAX(value) AS t_max, AVG(value) AS t_avg
FROM info
WHERE parameter = 't' AND dt_created > NOW() - INTERVAL 1 MINUTE) AS t,
(SELECT MIN(value) AS p_min, MAX(value) AS p_max, AVG(value) AS p_avg
FROM info
WHERE parameter = 'p' AND dt_created > NOW() - INTERVAL 1 MINUTE) AS p,
(SELECT MIN(value) AS h_min, MAX(value) AS h_max, AVG(value) AS h_avg
FROM info
WHERE parameter = 'h' AND dt_created > NOW() - INTERVAL 1 MINUTE) AS h;

Или совершенно стандартным запросом, возвращающим 3 строки данных:

SELECT parameter, MIN(value) AS mn, MAX(value) AS mx, AVG(value) AS av
FROM info
WHERE dt_created > NOW() - INTERVAL 1 MINUTE
GROUP BY parameter;
Яки БакичМастер (2108) 10 месяцев назад
Спасибо, Андрей! Вы очень помогли. Я до сего времени не сталкивался с БД, но пришло время. Но этого же самого времени не хватало на чтение мануалов. Так то я устраню этот пробел.
Яки БакичМастер (2108) 10 месяцев назад
Применил последний вариант.
Если не сложно. Ещё дополнение к вопросу. А если в GROUP BY требуется ещё timestamp?
Тогда вся схема летит к чертям.
Как я говорил у меня 3 сенсора в 15 местах. То есть раз в минуту БД пополняется на 45 строк. Так вот когда добавляю в GROUP BY timestamp (в SELECT) разумеется тоже, то по запросу вылетает 45 строк. Столбцы min, max, avg выдают одинаковые значения.
Я так понимаю, потому что он берёт один единственный замер с сенсора и ясно, что мин, макс и сред там равны. Но мне то надо, что бы он брал по всем сенсорам из этого замера и оттуда считал.
Андрей Искусственный Интеллект (149634) Для этого я и добавил в запрос WHERE - чтобы в выборку попали только те измерения, которые укладываются во временной интервал (dt_created - это я так назвал поле, в котором находится время измерения). Если ты хочешь получить данные сразу за несколько временных интервалов, то надо в GROUP BY преобразовывать timestamp в значение, которое будет одинаковым у вех измерений в группе. Например, отбросить секунды.
Остальные ответы
Александр Александр Ученик (189) 10 месяцев назад
да. среднее Это avg, min, max это думаю понятно. Всё одним запросом
Яки БакичМастер (2108) 10 месяцев назад
вы видимо не поняли вопроса. У меня разные данные в одной таблице. У меня давление, например 1020 Гпа, влажность 55% и температура +10. Какое среднее тут?
Александр Александр Ученик (189) Может найдёте тут ответ https://qa-help.ru/questions/srednee-znachenie-dlya-dvukh-stolbczov-sql Пишут что простая математика.
Jurijus Zaksas Искусственный Интеллект (282069) 10 месяцев назад
В принципе, тебе ничто не мешает считывать данные из твоей таблицы сколько хочешь раз. Но! У каждого набора измерений должен быть какой-то общий признак, характеризующий, что это один и тот же набор. Примерно так:

SELECT T1.VALUE AS TEMPERATURE, T2.VALUE AS MOISTURE
FROM YOUR_TABLE T1
INNER JOIN YOUR_TABLE T2
ON T1.MEASURE_ID=T2.MEASURE_ID
WHERE T1.PARAMETER='TEMPERATURE'
AND T2.PARAMETER='MOISTURE'

Ну, как получить последнюю минуту, минимумы и прочее - разберешься уже, главное принцип.
Похожие вопросы
Также спрашивают