mysql - 合并联合查询选择的 2 行

标签 mysql union

好吧,我遇到了一个非常奇怪的问题。

我正在尝试从 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

这会产生以下结果: enter image description here

我知道的问题是,当两个表都包含一个条目时,我从查询中得到两行。我想将它们合并到一行,因此结果中每个时间戳只有 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/

相关文章:

java - Fusion Charts FusionTime 从 mySQL 制作时间序列图表

MYSQL - Union SELECT 和 GROUP BY 不起作用

mysql - AS 不使用 COUNT(*) 和 UNION

php - MySQL UNION SELECT 直到找到?

php - 如何从 php 中的 db 确定今天日期以下的日期

php - MySQL:理解sql代码

MySQL 错误 #1064 靠近 UNION 版本 : 5. 5.27

php - MYSQL查询JOIN多个字段到一个字段

php - curl 多请求分割结果数组

php - 从一个 MySQL 表的两行中获取 id,然后使用 PHP 将这些值输入到另一个 MySQL 表的一行中