好的,我有一个非常奇怪的问题。
我正在尝试从mysql数据库加载一些传感器数据。表结构如下所示:
+-----------------+---------------------+--------------+
+ PK [bigint(20)] + timed [bigint(20)] + NO2 [double] +
+-----------------+---------------------+--------------+
现在来了困难的部分。有两个相同的表具有与上述完全相同的模式。一个用于原始数据,另一个用于验证数据。
在数据得到验证之前,通常需要大约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会显示在错误的列中?
答案 0 :(得分:1)
问题是您在最终数据中获得两个行。你需要再次聚合。此外,由于您希望在最终结果中同时使用这两个值,因此应使用union all
而不是union
。 union
删除重复项,这是不必要的,因为两个子查询之间的行不会相同:
SELECT max(mergedData.rawValue),
max(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 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,
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
GROUP BY years, months, days
ORDER BY timeValue
答案 1 :(得分:1)
在与union一起使用的查询中,列的顺序必须相同。您的查询应类似于:
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)中使用聚合函数,所以您将获得所需的结果。