我有一个包含多个服务器信息的数据库:
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值。
我怎么能得到这个?
由于
答案 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表并在左连接中使用它...可能是你最好的选择。否则你将在子查询中使用工会,而且它很难管理。