where子句sql并显示NULL值

时间:2014-10-06 16:06:47

标签: mysql sql

我有一个包含多个服务器信息的数据库:

mysql> select DATE_FORMAT(timestamp,'%M %Y') as 'Mois',AVG(value_perf) as 'moy' from info WHERE     server = 'pi4' GROUP BY MONTH(timestamp);
+----------------+-----------+
| Mois           | moy       |
+----------------+-----------+
| June 2014      | 98.465500 |
| July 2014      | 98.854516 |
| August 2014    | 98.227097 |
| September 2014 | 95.008667 |
| October 2014   | 77.880000 |
+----------------+-----------+
5 rows in set (0.00 sec)

然而,每个pi服务器都有不同的开始日期(6月的pi4统计数据,但1月的pi1统计数据)

示例:

mysql> select DISTINCT DATE_FORMAT(timestamp,'%M %Y') as 'Mois'  from info ORDER BY timestamp;
+----------------+
| Mois           |
+----------------+
| January 2014   |
| February 2014  |
| March 2014     |
| April 2014     |
| May 2014       |
| June 2014      |
| July 2014      |
| August 2014    |
| September 2014 |
| October 2014   |

+ ---------------- +

我想要一个查询来获得每台服务器的平均分数,但是最大的视图,包括NULL。

pi4的例子:

+----------------+-----------+
| Mois           | moy       |
+----------------+-----------+
| January 2014   | NULL      |
| February 2014  | NULL      |
| March 2014     | NULL      |
| April 2014     | NULL      |
| May 2014       | NULL      |
| June 2014      | 98.465500 |
| July 2014      | 98.854516 |
| August 2014    | 98.227097 |
| September 2014 | 95.008667 |
| October 2014   | 77.880000 |
+----------------+-----------+

Ps:这是数据库结构的一个例子

mysql> select * from info limit 10;
+----+------------+-----------+------------+-------------+
| id | timestamp  | server    | value_perf | value_avail |
+----+------------+-----------+------------+-------------+
| 45 | 2014-06-11 | pi4       |      98.33 |       99.91 |
| 46 | 2014-06-12 | pi4       |      97.92 |      100.00 |
| 52 | 2014-06-18 | pi4       |      98.15 |       99.97 |
| 54 | 2014-06-20 | pi        |      98.33 |       99.94 |
+----+------------+-----------+------------+-------------+

我希望每个月的平均值,不可用的月数为NULL值。

我怎么能得到这个?

由于

1 个答案:

答案 0 :(得分:0)

实现目标的最简单方法是创建日期查找表。像

这样的东西
CREATE TABLE `month_lookup` (
  `month_year` varchar(30),
  `st` datetime,
  `en` datetime,
  PRIMARY KEY (`month_year`),
  KEY `st` (`st`)
  KEY `end` (`end`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

然后插入每个月的开始和结束日期的数据。继续进行并填充1970年至2070年或其他东西。这张桌子可以派上用场。示例行看起来像

month-year     st                       en
Jan-2014       2014-01-01 00:00:00      2014-01-31 23:59:59

然后你能做的就是这样:

SELECT a.month_year, avg(b.value_perf) AS moy
FROM month_lookup AS a
LEFT JOIN info AS b
ON b.timestamp BETWEEN a.st AND b.en
GROUP BY a.month_year, b.server;

如果你单独使用st_end(st,en)代替st和en,那么month_lookup表上的索引可能会更好,但你必须测试一下...我不记得了如果一个复合索引可以帮助你使用join ... between子句

,那么我的头脑

无论哪种方式,创建一个month_lookup表并在左连接中使用它...可能是你最好的选择。否则你将在子查询中使用工会,而且它很难管理。