【问题标题】:Select min (also max & avg) from table together with timestamp of the event从表中选择最小值(也是最大值和平均值)以及事件的时间戳
【发布时间】:2019-04-24 10:49:14
【问题描述】:

我有几个这样的表:

> "dsid"    "tag"   "timestamp" "value"  
> "989" "EE"    "1445162347"    "931.647"
> "990" "PO"    "1445162347"    "0.087" 
> "991" "EE"    "1445163247"    "931.669"
> "992" "PO"    "1445163247"    "0.089"
> "993" "EE"    "1445164147"    "931.692"
> "994" "PO"    "1445164147"    "0.085"
> "995" "EE"    "1445165047"    "931.715"
> "996" "PO"    "1445165047"    "0.090"

EE 是电表的计数(以 kWh 为单位),PO 是电表上的功率(以 kW 为单位),每 15 分钟从电表读取数据并写入数据库。

我正在寻找带有标签“PO”的所有价值的最大值,这就是我排除所有“EE”标签的原因。我想要返回最高值的代码,它是根据时间戳,它有标签“PO”

我打算使用该代码来扩展具有 MAX、MIN 和 AVG 值及其相应时间戳的 grafana 仪表板(已经存在)。

这是我到目前为止的代码,但它似乎总是选择我在 WHERE 子句中提供的时间范围内的第一个值:

'''SELECT
    FROM_UNIXTIME(timestamp) as time_sec,
    '1P2' AS Meter,
    tag as metric,
    MIN(value) AS MIN,
    MAX(VALUE) AS MAX,
    AVG(VALUE) AS AVG
  FROM `WSE_KA-KHW_1P2`
  WHERE TAG NOT IN ('EE')
'''

目前我得到这个输出:

"time_sec"  "Meter" "metric"    "MIN"   "MAX" "AVG"
"2015-10-13 08:14:07"   "1P2"   "PO"    "0.000000"  "6.404" "3.2"

我想要的是这样的:

"time_sec"  "Meter" "metric"    "MIN"   "MAX"  "AVG"
"2015-10-13 08:14:07"   "1P2"   "PO"    "0.1"   ""  ""
"2015-12-13 10:14:07"   "1P2"   "PO"    ""  "6.404"  ""
""  "1P2"   "PO"    ""  ""  "3.2"

根据要求,这里有几行插入脚本代码:

INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (909, 'EE', 1445126346, '930.647', 1445125500, 1445126400, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (910, 'PO', 1445126346, '0.088', 1445125500, 1445126400, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (911, 'EE', 1445127246, '930.669', 1445126400, 1445127300, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (912, 'PO', 1445127246, '0.087', 1445126400, 1445127300, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (913, 'EE', 1445128146, '930.691', 1445127300, 1445128200, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (914, 'PO', 1445128146, '0.087', 1445127300, 1445128200, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (915, 'EE', 1445129046, '930.718', 1445128200, 1445129100, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (916, 'PO', 1445129046, '0.138', 1445128200, 1445129100, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (917, 'EE', 1445129947, '930.752', 1445129100, 1445130000, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (918, 'PO', 1445129947, '0.134', 1445129100, 1445130000, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (919, 'EE', 1445130847, '930.782', 1445130000, 1445130900, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (920, 'PO', 1445130847, '0.088', 1445130000, 1445130900, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (921, 'EE', 1445131747, '930.804', 1445130900, 1445131800, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (922, 'PO', 1445131747, '0.087', 1445130900, 1445131800, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (923, 'EE', 1445132647, '930.826', 1445131800, 1445132700, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (924, 'PO', 1445132647, '0.086', 1445131800, 1445132700, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (925, 'EE', 1445133547, '930.848', 1445132700, 1445133600, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (926, 'PO', 1445133547, '0.086', 1445132700, 1445133600, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (927, 'EE', 1445134447, '930.870', 1445133600, 1445134500, 0);
INSERT INTO `WSE_KA-KHW_1P2` (`dsid`, `tag`, `timestamp`, `value`, `startts`, `correctts`, `isfixed`) VALUES (928, 'PO', 1445134447, '0.087', 1445133600, 1445134500, 0);

value 后面的附加列无关紧要...

感谢@symcbean 我现在离我需要实现的目标更近了一点:

SELECT records.*, aggregated.*
 FROM
 (
 SELECT
 from_unixtime(TIMESTAMP),
 tag AS metric,
 MAX(VALUE) AS 1P2_MAX,
 AVG(VALUE) AS 1P2_AVG
 FROM `WSE_KA-KHW_1P2`
 WHERE TAG NOT IN ('EE')
 AND from_unixtime(TIMESTAMP BETWEEN FROM_UNIXTIME(1546297200) AND FROM_UNIXTIME(1577833199))
 ) records JOIN
 (
 SELECT
 tag AS metric,
 MAX(VALUE) AS 1P2_MAX,
 AVG(VALUE) AS 1P2_AVG
 FROM `WSE_KA-KHW_1P2`
 WHERE TAG NOT IN ('EE')
 AND from_unixtime(TIMESTAMP BETWEEN FROM_UNIXTIME(1546297200) AND FROM_UNIXTIME(1577833199))
 GROUP BY metric
 ) aggregated ON
 records.metric=aggregated.metric

我已经在 grafana 中使用了其中的三个,得到了一个不错的表,但它总是选择数据库中的第一个时间值作为时间戳。但我需要它从 1P2_MAX 输出时间戳。这样我就可以知道 MAX 到底是什么时候发生的……

目前的输出是这样的:

"from_unixtime(TIMESTAMP)"  "metric"    "1P2_MAX"   "1P2_AVG"   "metric"    "1P2_MAX"   "1P2_AVG"
"2015-10-13 08:14:07"   "PO"    "6.404" "0,4250229947656381"    "PO"    "6.404" "0,4250229947656381"

【问题讨论】:

  • 可以添加插入脚本吗? - 尝试修复的示例?
  • 我的SQL编码经验很基础所以一般不会:-(
  • 您只需在您的select * 结果上右键单击Export recordset to an external file - 并使用.sql 保存文件 - 这基本上是您的表格插入
  • 没听懂你的问题,我可以导出数据放在这里...
  • 可以有相同时间戳的不同标签吗?应该返回哪个标签?

标签: mysql mariadb grafana


【解决方案1】:

你需要GROUP BY FROM_UNIXTIME(timestamp), tag

(根据您的 DBMS 的配置方式,您可能需要在分组属性中包含文字)。

这是一个相当微不足道的 SQL 问题 - 如此之多以至于在此处键入答案而不是搜索重复项更快。

但是,尽管这回答了您提出的问题 - 看起来您提出了错误的问题。尽管您的示例数据有多行具有相同的标签和时间戳,但这似乎有点奇怪。如果您真的对聚合值感兴趣,我怀疑您可能希望对时间值进行四舍五入以获得更大的 bin。

更新基于下面的 cmets

如果您想要聚合值而不将它们与特定时间匹配......

SELECT records.*, aggregated.*
FROM
(
  SELECT *
  FROM `WSE_KA-KHW_1P2`
  WHERE TAG NOT IN ('EE')
  AND timestamp BETWEEN _____ AND _____
) records JOIN
(
  SELECT
  tag AS metric,
  MIN(value) AS minval,
  MAX(VALUE) AS maxval,
  AVG(VALUE) AS avgval
  FROM `WSE_KA-KHW_1P2`
  WHERE TAG NOT IN ('EE')
  AND timestamp BETWEEN _____ AND _____
  GROUP BY tag
) aggregated ON
records.tag=aggregated.tag

但这与您在随后的问题编辑中提出的不同:

我想要返回最高值的代码,并且它是根据带有标签“PO”的时间戳

这是一个新要求。虽然在您的示例数据中,PO 是“NOT IN (EE)”,但它不一定遵循该表达式是可交换的。撇开这一点不谈,您似乎在要求“分组最大值” - 您可以使用 max concat tricksub-query 解决这个问题

【讨论】:

  • 我尝试了其他几个不同的问题,但无法从那些给我预期输出的问题中获取代码。我会尽力使您的建议发挥作用并返回...
  • 如果添加建议的 GROUP BY FROM_UNIXTIME(timestamp), 标记我会从表中得到每一行的输出,我想要的只是具有最大值的一行。对于 AVG 和 MIN,稍后可以在 grafana 的附加面板中使用相同的查询
  • 否 - 添加 GROUP BY 将聚合具有相同时间戳和标签的值 - 这在您发布的数据集中不是唯一的,但请参阅我答案的最后一段。
  • @Smycbean 我正在寻找带有标签“PO”的所有值的最大值,这就是我排除所有“EE”标签的原因。我想要返回最高值的代码,并且它是根据具有标签“PO”的时间戳。我不知道如何更具体地问我的问题... :-(
  • 感谢您的补充,我离得更近了,但输出中的时间戳仍然错误。似乎是数据库中的第一个值,但不是 MAX 发生的时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
相关资源
最近更新 更多