【问题标题】:How to use result of first query in subquery如何在子查询中使用第一个查询的结果
【发布时间】:2018-08-15 13:23:08
【问题描述】:

我正在尝试针对 MySQL 数据库编写一个查询,以便在 grafana 仪表板中使用。当我从表中手动选择一个已知的时间戳时,我有一个有效的查询,但是当我事先不知道时间戳时,我的数据不正确。

目标是获取 4 个不同名称的 UsedSpaceMB 总量,但仅使用 1 个 TimeStmp。即 TimeStmp LIKE "%2018-07-27 16%"。如果查询中包含多个 TimeStmp,则 UsedpaceMB 的总量不正确。

表名是 Storage 字段为 TimeStmp、UsedSpaceMB 和 Name

Select TimeStmp, UsedSpaceMB, Name FROM Storage LIMIT 5;
+---------------------+-------------+------------------------+
| TimeStmp            | UsedSpaceMB | Name                   |
+---------------------+-------------+------------------------+
| 2018-07-27 16:02:07 |    61415607 | Array1                 |
| 2018-07-27 20:02:09 |    61896587 | Array1                 |
| 2018-07-28 00:02:17 |    61767053 | Array1                 |
| 2018-07-28 04:02:04 |    62175704 | Array1                 |
| 2018-07-28 08:02:10 |    62683011 | Array1                 |
+---------------------+-------------+------------------------+

SELECT DISTINCT NAME FROM Storage ORDER BY Name ASC;
+------------------------------+
| NAME                         |
+------------------------------+
| Array1                       |
| Array2                       |
| Array3                       |
| Array4                       |
+------------------------------+

此查询有效:

 SELECT
 TimeStmp as time,
'Used Capacity' as metric,
(SELECT SUM(UsedSpaceMB) as value)
FROM Storage
WHERE TimeStmp LIKE "%2018-07-27 16:%" AND Name IN ("Array1", "Array2", "Array3", "Array4")

(Grafana 示例,其中 To Time 设置为 2018-08-15 04:00)

 SELECT
 TimeStmp as time,
'Used Capacity' as metric,
(SELECT SUM(UsedSpaceMB) as value)
FROM Storage
WHERE TimeStmp >= FROM_UNIXTIME($__unixEpochTo(),'%Y-%m-%d %H') AND Name IN ("Array1", "Array2", "Array3", "Array4")

我真正想做的首先是在我的原始查询中选择 MAX(TimeStmp),然后在我的 WHERE 子句中使用它,以便我只搜索 1 个特定的 TimeStmp(即 WHERE TimeStmp = MAX(TimeStmp ) 或 HAVING TimeStmp = MAX(TimeStmp)。我不确定如何进行 JOIN 或使用 HAVING,因为当我执行此查询时我没有得到任何结果。

 SELECT
 TimeStmp as time,
'Used Capacity' as metric,
(SELECT SUM(UsedSpaceMB) as value)
FROM Storage
WHERE Name IN ("Array1", "Array2", "Array3", "Array4")
HAVING TimeStmp = MAX(TimeStmp)

预期结果:

SELECT (SELECT SUM(UsedSpaceMB)) FROM Storage WHERE TimeStmp LIKE "%2018-07-27 16:%" AND Name IN('Array1','Array2','Array3','Array4');
+---------------------------+
| (SELECT SUM(UsedSpaceMB)) |
+---------------------------+
|                 777379124 |
+---------------------------+

【问题讨论】:

  • 很可能只有一个时间戳具有最大值。那么,您想要获取已用空间的总和是什么意思?你能告诉我们你想要的输出是什么样的吗?
  • 结果将返回单个时间戳,但由于表中的名称中有多个时间戳,如果 TimeStmp 不等于 1 个单个时间戳,则结果总数会在多个时间戳上聚合。我编辑了原始问题以显示结果
  • Can you show us what your desired output looks like?
  • 添加在上面,如果这不是您需要的,请告诉我
  • 我很困惑。7 月 27 日不是最新的时间戳,甚至对于 Array1 组也不是。那么其他组呢?如果一个名称没有最大时间戳,它的已用空间是否不加到总和中?

标签: mysql time-series grafana


【解决方案1】:

如果您想要按名称列出的 UsedSpaceMB 列的总和(假设每个名称有多个行作为时间戳):

SELECT
    a.`Name`,
    a.`TimeStamp` as `time`,
    'Used Capacity' as `metric`,
    SUM(a.`UsedSpaceMB`) as `value`
FROM `Storage` a
JOIN (SELECT MAX(`TimeStamp`) as `tm`,`Name` 
        FROM `Storage` 
        WHERE `Name` IN ("Array1", "Array2", "Array3", "Array4")
    ) b
    ON a.`TimeStamp` = b.`tm` AND a.`Name` = b.`Name`
GROUP BY a.`Name`
ORDER BY a.`Name`

另外,当你可以使用 SUM(UsedSpaceMB) as value 时,不知道为什么你使用 (SELECT SUM(UsedSpaceMB) as value)

【讨论】:

  • 这个假设是正确的。但是,该查询给了我一个错误:错误 1064:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 12 行的“GROUP BY a.Name ORDER BY a.NAME”附近使用正确的语法
  • 糟糕!在 GROUP BY 之前留下一个分号。查看更新的答案
  • 另外,你应该用反引号引用列名和表名,以避免与保留字/函数/命令冲突。
  • 我一直在玩这个来弄明白,但它没有给我正确的数据。它只需要为 1 个单个时间戳行提取所有提到的 Names 的 UsedSpaceMB,其中该时间戳是 MAX(TimeStamp)。
  • 在我的回答中查看查询的更新。我修复了 JOIN 的 ON 子句
【解决方案2】:

这是你想要的吗?

SELECT SUM(UsedSpaceMB) AS total
FROM
(
    SELECT s1.UsedSpaceMB
    FROM Storage s1
    INNER JOIN
    (
        SELECT Name, MAX(TimeStmp) AS MaxTimeStmp
        FROM Storage
        GROUP BY Name
    ) s2
        ON s1.Name = s2.Name AND s1.TimeStmp = s2.MaxTimeStmp
) t;

【讨论】:

  • 不是,我会尝试在这里处理查询,并提供更多关于我期望结果的信息。不过谢谢!
  • @Ryan 你在这里的交流做得不好。 为什么我的回答错了?我别名为t 的子查询的结果是否至少返回了一些正确的数据?
猜你喜欢
  • 2015-03-16
  • 2013-11-01
  • 1970-01-01
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
  • 2018-12-18
  • 2012-06-03
  • 2022-11-18
相关资源
最近更新 更多