【问题标题】:Mysql query problems (total amount of time)Mysql查询问题(总时间)
【发布时间】:2018-11-26 16:35:55
【问题描述】:

我被困住了.. 我的加热器上的指示灯连接到树莓派。然后 pi 将随时间变化的状态(开和关)放入 mysql 数据库中。 在我使用 PHP 呈现数据之前,但我现在正在尝试 Grafana。而且我无法让 mysql 查询来呈现我想要的内容。

我需要知道在指定时间范围(通常是最后 24 小时)内加热器被激活的时间 (0/1)。而且我需要考虑到时间范围可能以“0”开头,这意味着在此之前加热器已经开启。如果它以“1”结尾也是一样的。 也可能是一天中它被激活的百分比。

有人可以帮帮我吗? 我正在寻找这样的结果

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

|价值 | secondsOfDay |日百分比 |

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

| 0 | 28800 | 33.3 |

| 1 | 57600 | 66.6 |

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

我已经准备好了: http://sqlfiddle.com/#!9/556364a

谢谢!

【问题讨论】:

  • 请将您现有的结构(表格格式、示例数据、您尝试过的查询)附加到您的问题中

标签: mysql date time grafana


【解决方案1】:

要获取所需数据,可以使用以下查询:

注意:根据CURRDATE(),示例将失败。你可以。将CURDATE() 替换为固定值,例如2018-11-27

解释:

  • 查询正在将表与自身连接起来,同时考虑到开/关相互跟随 (L.id = R.id -1)
  • 查询选择任何结果,其中“on”或“off”为today
  • 如果on 是昨天,则准时“更正”为今天的00:00:00case when L.Time < CURDATE() then CURDATE() else L.Time end as onTime
  • 如果最后一个条目是on,则关闭时间将“更正”为明天的00:00:00COALESCE(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

如果最后一个状态是on,则使用NOW() 计算秒数的示例:http://sqlfiddle.com/#!9/3c6227/1

如果您只需要其中的聚合,您可以使用另一个环绕选择并通过知道一天有 86400 秒来计算百分比:

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

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

【讨论】:

  • 这几乎是完美的。但是如果第一个值为 0,我不能让第一个 ontime 成为 CURDATE() (如果第一个值为 0,那么这意味着它已经在那之前的时间)。有点像最后一行,如果它在 1 结束。
  • @D_69 这种情况也应该包括在内,除了您将在系统中拥有的 VERY FIRST 值。 (对于任何连续的一天,如果它以“0”开头,它就会被覆盖并且不再是问题)。但是由于这个值应该在你的系统实时出现一次,我会忽略它。
  • 我刚刚注意到没有 ID 列。主键是日期。有没有办法修改这个sqlfiddle.com/#!9/4c7edd
  • @D_69 对于这种方法:不。它依赖于这样一个事实,即开/关总是以nn+1 的ID 发生。如果你没有 id,用 mysql 很难实现输出。只“获取”“Today”的所有内容,并在您使用的编程语言中对结果进行后处理会更容易。
【解决方案2】:

试试这个

    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;

【讨论】:

  • 也感谢您的帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-01
  • 2011-11-14
相关资源
最近更新 更多