[英]SQL Query to Group “Blocks” of Date/Time Activity?
我在表中有數據,這是服務器活動的日志數據。 這是它的樣子(#列不是數據庫或輸出的一部分,但是我可以在下面的注釋中引用該數據):
# | DateStamp | Server
- | ------------------- | ---------
1 | 2016-12-01 03:15:19 | Server 1
2 | 2016-12-01 03:17:19 | Server 2
3 | 2016-12-01 03:17:24 | Server 2
4 | 2016-12-01 03:18:01 | Server 1
5 | 2016-12-01 03:18:07 | Server 3
6 | 2016-12-01 04:01:03 | Server 3
7 | 2016-12-01 07:18:47 | Server 1
8 | 2016-12-01 07:19:23 | Server 1
9 | 2016-12-01 09:19:39 | Server 2
10| 2016-12-01 11:19:54 | Server 3
我想寫一個輸出的查詢:
# | Server | Online | Offline
- | -------- | ------------------- | -------------------
1 | Server 1 | 2016-12-01 03:15:19 | 2016-12-01 03:18:01
2 | Server 2 | 2016-12-01 03:17:19 | 2016-12-01 03:17:24
3 | Server 3 | 2016-12-01 03:18:07 | 2016-12-01 03:18:07
4 | Server 1 | 2016-12-01 07:18:47 | 2016-12-01 07:19:23
5 | Server 2 | 2016-12-01 09:19:39 | 2016-12-01 09:19:39
6 | Server 3 | 2016-12-01 11:19:54 | (still online)
筆記:
我很想知道如何查詢,並根據上面的輸出和注釋對結果進行分組。 如果您需要更多信息來建議解決方案,請與我們聯系。
1)首先,您應該將日志加載到MySQL DB中:
# Optionally
#drop table if exists srv_logs;
create table srv_logs (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`datetime` DATETIME ,
`server` VARCHAR(300),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOAD DATA INFILE 'yourfile.log'
INTO TABLE srv_logs
CHARSET utf8
FIELDS TERMINATED BY '|'
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n' IGNORE 2 LINES (
`id`,
`datetime`,
`server`
);
2)創建/填充初始數據您的停機時間表:
create table srv_downtime (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`server` VARCHAR(300),
`online` DATETIME ,
`offline` DATETIME ,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into srv_downtime (`server`, `online`, `offline`)
SELECT l.server, MAX(l.datetime), null
FROM srv_logs l
left join srv_logs l2
on l.server = l2.server
and l.datetime > l2.datetime
and TIMESTAMPDIFF(MINUTE,l2.datetime,l.datetime) < 60
where l2.id is null
GROUP BY l.server
3)反復調用此插入,直到不添加新行,它將向底部添加新行(前一工作期)
insert into srv_downtime (`server`, `online`, `offline`)
(select a.server, min(l2.datetime), offline from
(SELECT d.server, max(l.datetime) as offline
FROM srv_downtime d
left join srv_logs l
on l.server = d.server
and d.online > l.datetime
group by l.server
) a
left join srv_logs l2
on a.offline > l2.datetime
and l2.server = a.server
and TIMESTAMPDIFF(MINUTE, l2.datetime, a.offline) < 60
group by a.server
)
因此,在這3個步驟之后的示例數據集上,結果似乎是正確的:
Server 1 | 2016-12-01 03:15:19 | 2016-12-01 03:18:01
Server 1 | 2016-12-01 07:18:47 | NULL
Server 2 | 2016-12-01 03:17:19 | 2016-12-01 03:17:24
Server 2 | 2016-12-01 09:19:39 | NULL
Server 3 | 2016-12-01 03:18:07 | 2016-12-01 04:01:03
Server 3 | 2016-12-01 11:19:54 | NULL
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.