在MySQL行中添加值

时间:2015-03-04 02:28:23

标签: mysql logging grouping algebra

我有一个表,用于存储已解析的服务器日志:

mysql> SELECT id,date,message_type FROM log_entry LIMIT 10 ;                 
+----+---------------------+--------------+
| id | date                | message_type |
+----+---------------------+--------------+
|  1 | 2015-01-08 18:13:15 |            2 |
|  2 | 2015-01-08 18:13:14 |            1 |
|  3 | 2015-01-08 18:13:12 |            1 |
|  4 | 2015-01-08 18:13:11 |            1 |
|  5 | 2015-01-08 18:13:11 |            1 |
|  6 | 2015-01-08 18:13:11 |            1 |
|  7 | 2015-01-08 18:13:10 |            1 |
|  8 | 2015-01-08 18:13:08 |            1 |
|  9 | 2015-01-08 18:13:07 |            1 |
| 10 | 2015-01-08 18:13:06 |          512 |
+----+---------------------+--------------+

每个日志按 message_type 进行分类。我也可以按小时分组:

mysql> select DAY(date) as day, HOUR(date) as hour, message_type, count(message_type) FROM log_entry WHERE date >= CURDATE() - INTERVAL 2 MONTH AND message_type BETWEEN 1 AND 4 GROUP BY day,hour,message_type ORDER BY date ASC LIMIT 3;
+------+------+--------------+---------------------+
| day  | hour | message_type | count(message_type) |
+------+------+--------------+---------------------+
|    8 |   18 |            1 |                 177 |
|    8 |   18 |            2 |                  61 |
|    8 |   18 |            4 |                  14 |
+------+------+--------------+---------------------+

在此示例中,在特定日期的第8天和第18小时,我有 177 条目,其message_type为1, 61 ,类型为2,< 4级以上强> 14 。

我想每小时得到以下计算:

type(1) - type(2) - type(4)

在这种情况下会返回

+------+------+--------------+---------------------+
| day  | hour | result                             |
+------+------+--------------+---------------------+
|    8 |   18 | 102                                |
+------+------+--------------+---------------------+

我这样做是因为我想在我正在运行的服务器上创建一个显示每小时活动的图表。类型1条目表示有人连接,类型2表示存在正常断开连接,类型4表示存在超时。

这在数据库中是可行的吗?还是应该在应用程序层上执行此操作?

1 个答案:

答案 0 :(得分:1)

您可以使用SUM()函数和CASE语句计算每个message_type并进行数学运算。

SELECT   DAY(date) as day, HOUR(date) as hour,  
         SUM(CASE WHEN message_type = 1 THEN 1 ELSE 0 END) -
         SUM(CASE WHEN message_type = 2 THEN 1 ELSE 0 END) -
         SUM(CASE WHEN message_type = 4 THEN 1 ELSE 0 END) as result
FROM     log_entry 
WHERE    date >= CURDATE() - INTERVAL 2 MONTH 
         AND message_type BETWEEN 1 AND 4 
GROUP BY day,hour;