好吧,我遇到了一个非常奇怪的问题。
我正在尝试从 mysql 数据库加载一些传感器数据。表结构如下所示:
+-----------------+---------------------+--------------+
+ PK [bigint(20)] + timed [bigint(20)] + NO2 [double] +
+-----------------+---------------------+--------------+
- PK为主键
- timed 是以毫秒为单位存储的时间戳,从 01.01.1970(Linux 时间戳)开始
- NO2测量的 NO2 浓度(以 ppb 为单位,十亿分之一)
现在是最困难的部分。有两个相同的表具有与上述完全相同的架构。一份用于原始数据,一份用于验证数据。
数据得到验证之前通常需要 1 个月左右的时间。因此,当我显示来自传感器的实时数据时,我使用 UNION
合并这两个表。验证值应始终优先于原始值。
另外,我只加载每日平均值。
这是我迄今为止创建的 SQL 查询:
SELECT
mergedData.rawValue,
mergedData.validatedValue,
CAST(IF(mergedData.validatedValue IS NULL, mergedData.rawValue, mergedData.validatedValue) AS DECIMAL(65, 2)) as sensorValue,
timeValue,
IsValid
FROM
(SELECT
Month(FROM_UNIXTIME(timed / 1000)) as months,
Year(FROM_UNIXTIME(timed / 1000)) as years,
DAYOFMONTH(FROM_UNIXTIME(timed / 1000)) as days,
HOUR(FROM_UNIXTIME(timed / 1000)) as hours,
MINUTE(FROM_UNIXTIME(timed / 1000)) as minutes,
avg(NO2) as rawValue,
FROM_UNIXTIME(timed / 1000) as timeValue,
IF(NO2 IS NOT NULL, 1, 0) as IsValid,
NULL as validatedValue
FROM
nabelnrt_pay
WHERE
timed > 1360236120000
AND timed < 1391772120000
GROUP BY years, months, days
UNION
SELECT
Month(FROM_UNIXTIME(timed / 1000)) as months,
Year(FROM_UNIXTIME(timed / 1000)) as years,
DAYOFMONTH(FROM_UNIXTIME(timed / 1000)) as days,
HOUR(FROM_UNIXTIME(timed / 1000)) as hours,
MINUTE(FROM_UNIXTIME(timed / 1000)) as minutes,
avg(NO2) as validatedValue,
FROM_UNIXTIME(timed / 1000) as timeValue,
IF(NO2 IS NOT NULL, 1, 0) as IsValid,
NULL as rawValue
FROM
nabelvalidated_pay
WHERE
timed > 1360236120000
AND timed < 1391772120000
GROUP BY years, months, days) as mergedData ORDER BY timeValue
这会产生以下结果:
我知道的问题是,当两个表都包含一个条目时,我从查询中得到两行。我想将它们合并到一行,因此结果中每个时间戳只有 1 行。另外,由于某种原因,mergedData.validatedValue
的数据显示在 rawValue
而不是 validatedValue
中。
有人可以告诉我如何将这两行合并为 1 个结果行以及为什么 validatedData 显示在错误的列中?
最佳答案
与联合一起使用的查询中的列顺序必须相同。您的查询应该类似于:
SELECT max(mergedData.rawValue),
max(mergedData.validatedValue),
CAST(IF(max(mergedData.validatedValue) IS NULL, max(mergedData.rawValue),
max(mergedData.validatedValue)) AS DECIMAL(65, 2)) as sensorValue,
max(timeValue),
max(IsValid)
FROM ((SELECT Month(FROM_UNIXTIME(timed / 1000)) as months,
Year(FROM_UNIXTIME(timed / 1000)) as years,
DAYOFMONTH(FROM_UNIXTIME(timed / 1000)) as days,
HOUR(FROM_UNIXTIME(timed / 1000)) as hours,
MINUTE(FROM_UNIXTIME(timed / 1000)) as minutes,
avg(NO2) as rawValue,
FROM_UNIXTIME(timed / 1000) as timeValue,
0 IsValid,
NULL as validatedValue
FROM nabelnrt_pay
WHERE timed > 1360236120000 AND timed < 1391772120000
GROUP BY years, months, days
)
UNION ALL
(SELECT Month(FROM_UNIXTIME(timed / 1000)) as months,
Year(FROM_UNIXTIME(timed / 1000)) as years,
DAYOFMONTH(FROM_UNIXTIME(timed / 1000)) as days,
HOUR(FROM_UNIXTIME(timed / 1000)) as hours,
MINUTE(FROM_UNIXTIME(timed / 1000)) as minutes,
NULL as rawValue,
FROM_UNIXTIME(timed / 1000) as timeValue,
1 AS IsValid,
avg(NO2) as validatedValue
FROM nabelvalidated_pay
WHERE timed > 1360236120000 AND timed < 1391772120000
GROUP BY years, months, days
)
) as mergedData
GROUP BY years, months, days
ORDER BY timeValue
进行此更改后,您将获得两行用于经过验证的读数,一行用于未经验证的读数。您使用的最后一个组将对这两行进行分组以进行验证读数。因为您在选择中使用聚合函数,例如 max(mergedData.rawValue),您将获得所需的结果。
关于mysql - 合并联合查询选择的 2 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21628426/