UNION / GROUP BY - 防止NULL值

时间:2018-03-08 12:52:54

标签: mysql sql sql-server

我有三个包含天气观测的MySQL表。现在我正在尝试查询按小时分组的所有这些表中的数据。表格如下:

TABLE 1
--------------------------------------------------------------------
station     time        temperature     pressure        humidity
--------------------------------------------------------------------
10637       1520512345  22.9            NULL            NULL

TABLE 2
-------------------------------------------------------------------
station     time        temperature     pressure        humidity
-------------------------------------------------------------------
10637       1520512345  NULL            1016            NULL

TABLE 3
-------------------------------------------------------------------
station     time        temperature     pressure        humidity
-------------------------------------------------------------------
10637       1520512345  NULL            NULL            76

目前,我使用UNIONGROUP BY来查询每小时汇总:

SELECT *
FROM ((SELECT `time`,`temperature`,`pressure`,`humidity`
       FROM `table_1`
       WHERE `station` = 10637
      ) UNION
      (SELECT `time`,`temperature`,`pressure`,`humidity`
       FROM `table_2`
       WHERE `station` = 10637
      ) UNION
      (SELECT `time`,`temperature`,`pressure`,`humidity`
       FROM `table_3`
       WHERE `station` = 10637
      )
     ) AS `hourly`
GROUP BY DATE_FORMAT(FROM_UNIXTIME(`time`), '%Y %m %d %H')
ORDER BY `time`

查询有效。每小时需要一行可用行。但是,如示例所示,某些表包含其他表中不可用的数据。这会在输出中导致许多不必要的NULL值。如何更改查询以使输出包含NOT NULL的所有数据的聚合?

2 个答案:

答案 0 :(得分:4)

请勿将select *group by一起使用。它是一种反模式,在大多数情况下不受其他数据库的支持。接受挑战。弄清楚如何组合结果。

在这种情况下,简单的聚合函数可以工作:

SELECT DATE_FORMAT(FROM_UNIXTIME(`time`), '%Y %m %d %H') as yyyymmddhh,
       AVG(temperature) as temperature,
       AVG(pressure) as pressure,
       AVG(humidity) as humidity
FROM ((SELECT time, temperature, pressure, humidity
       FROM `table_1`
       WHERE `station` = 10637
      ) UNION ALL
      (SELECT time, temperature, pressure, humidity
       FROM `table_2`
       WHERE `station` = 10637
      ) UNION ALL
      (SELECT time, temperature, pressure, humidity
       FROM `table_3`
       WHERE `station` = 10637
      )
     ) hourly
GROUP BY DATE_FORMAT(FROM_UNIXTIME(`time`), '%Y %m %d %H')
ORDER BY yyyymmddhh

答案 1 :(得分:0)

不是答案。评论太长了......

我很好奇为什么你不能将所有数据存储在一个表中:

--------------------------------------------------------------------
station     time        temperature     pressure        humidity
--------------------------------------------------------------------
10637       1520512345  22.9            1016            76

无论如何,您可以考虑修改架构如下:

station*  time*      metric*       value
-----------------------------------------
10637     1520512345 temperature     22.9            
10637     1520512345 pressure      1016.0            
10637     1520512345 humidity        76.0

* = (component of) PRIMARY KEY