Mysql запросов (общее количество времени) - PullRequest
0 голосов
/ 26 ноября 2018

Я застрял .. У меня есть индикаторы на моем обогревателе, подключенном к Raspberry Pi.Затем пи помещает измененное состояние (включается и выключается) со временем в базу данных mysql.Раньше я использовал PHP для представления данных, но сейчас я пробую Grafana.И я не могу получить запрос mysql для представления того, что я хочу.

Мне нужно знать, сколько раз был активирован нагреватель (0/1) в указанном диапазоне времени (обычно последние 24 часа).И я должен принять во внимание, что временной диапазон может начинаться с «0», что означает, что нагреватель был на время до этого.И то же самое, если оно заканчивается «1».И, возможно, также процент дня, когда он был активирован.

Может кто-нибудь помочь мне?Я ищу такой результат

+ ------- + -------------- + -------------- +

|значение |secondsOfDay |PercentOfDay |

+ ------- + -------------- + -------------- +

|0 |28800 |33,3 |

|1 |57600 |66,6 |

+ ------- + -------------- + -------------- +

Я подготовил: http://sqlfiddle.com/#!9/556364a

Спасибо!

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Чтобы получить необходимые данные, вы можете использовать следующий запрос:

ПРИМЕЧАНИЕ: В зависимости от CURRDATE() примеры не пройдут.Вы можете ofc.замените CURDATE() фиксированным значением, таким как 2018-11-27;

Объяснение:

  • Запрос соединяет таблицу с самим собой, учитывая, что вкл / выкл следует друг за другом(L.id = R.id -1)
  • Запрос выбирает любой результат, где «включено» или «выключено» равно today.
  • ЕСЛИ on было вчера, время включения равно «исправлено "до 00:00:00 сегодняшнего дня: case when L.Time < CURDATE() then CURDATE() else L.Time end as onTime
  • ЕСЛИ последняя запись on, время отключения" исправлено "до 00:00:00 завтрашнего дня: COALESCE(R.time, CURDATE() + Interval 1 day) (примечание: возможно, выхотите использовать NOW() вместо CURDATE() + Interval 1 day, чтобы иметь текущее количество секунд до «сейчас»)
  • Те же два метода используются для вычисления секунд работы.

Запрос:

SELECT 
  L.playtime_id AS LID,
  R.playtime_id AS RID,
  case when L.Time < CURDATE() then CURDATE() else L.Time end as onTime,
  COALESCE(R.time, CURDATE() + Interval 1 day) AS offTime,
  (  
      UNIX_TIMESTAMP(COALESCE(R.time, CURDATE() + Interval 1 day)) -  
      UNIX_TIMESTAMP(case when L.Time < CURDATE() then CURDATE() else L.Time end)
  ) as RunningSeconds
FROM item0005 as L
LEFT JOIN item0005 AS R 
ON L.playtime_id = R.playtime_id -1

WHERE
  L.`value` = 1 AND
  (
    DATE(L.Time) = CURDATE() OR
    DATE (R.Time) = CURDATE()
  )
;

Пример результата:

 LID    RID     onTime                  offTime                 RunningSeconds
 2      3       2018-11-27T09:00:00Z    2018-11-27T11:26:24Z    8784
 4      5       2018-11-27T11:26:27Z    2018-11-27T11:28:29Z    122
 6      7       2018-11-27T11:29:39Z    2018-11-27T11:39:55Z    616
 8      (null)  2018-11-27T11:50:55Z    2018-11-28T00:00:00Z    43745

Пример, предполагающий 00:00:00 завтрашнего дня: http://sqlfiddle.com/#!9/20bc14/1

Пример использования NOW() для подсчета секунд, если последним состоянием является on: http://sqlfiddle.com/#!9/3c6227/1

Если вам просто нужны агрегаты из этого, вы можете использовать другой Surrounding Select и рассчитать процент, знаядень имеет 86400 секунд:

SELECT
  SUM(RunningSeconds) AS RunningSeconds,
  SUM(RunningSeconds) / 86400 * 100 AS PercentageRunning
 FROM (
   ...
 ) as temp;

http://sqlfiddle.com/#!9/20bc14/5

0 голосов
/ 26 ноября 2018

попробуйте

    SELECT VALUE, SUM(TIME_TO_SEC(TIMEDIFF(T2,T1))), 100*SUM(TIME_TO_SEC(TIMEDIFF(T2,T1)))/86400 FROM
(SELECT A.VALUE AS VALUE, COALESCE(B.TIME, TIMESTAMP(CURDATE()-2)) AS T1, A.TIME AS T2
FROM ITEM0005 A
LEFT JOIN ITEM0005 B
ON A.PLAYTIME_ID-1= B.PLAYTIME_ID
WHERE A.VALUE='0'
UNION
SELECT '1' AS VALUE, A.TIME AS T1, COALESCE(B.TIME, TIMESTAMP(CURDATE()-1)) AS T2
FROM ITEM0005 A
LEFT JOIN ITEM0005 B
ON A.PLAYTIME_ID= B.PLAYTIME_ID-1
WHERE A.VALUE='0') C
GROUP BY VALUE;
...