按 mysql / MariaDB 中的变量范围分组
Group by a variable range in mysql / MariaDB
我有一个历史日志,我想总结一些条目。间隔应该是5秒
例如:
我有一个列表
date_start | date_end | count | somestring
2015-09-15 12:04:09 | 2015-09-15 12:04:09| 1 | xyz
2015-09-15 12:05:09 | 2015-09-15 12:05:09| 1 | xyz
2015-09-15 12:05:10 | 2015-09-15 12:05:10| 1 | xyz
2015-09-15 12:05:11 | 2015-09-15 12:05:11| 1 | xyz
2015-09-15 12:06:09 | 2015-09-15 12:06:09| 1 | xyz
我现在想要一个像
这样的输出
date_start | date_end | count | somestring
2015-09-15 12:04:09 | 2015-09-15 12:04:09| 1 | xyz
2015-09-15 12:05:09 | 2015-09-15 12:05:11| 3 | xyz <--
2015-09-15 12:06:09 | 2015-09-15 12:06:09| 1 | xyz
因此,如果在 5 秒的间隔内出现重复,我想将其归为一个条目。但如果 1 小时内有多个条目,每个最大值。相隔 5 秒我也想把所有这些条目数一遍。
有人知道办法吗?我已经为此工作了几个星期了:(
编辑:
对 Bernd 的回答和评论:
非常感谢,您的查询输出为:
谢谢@Bernd。问题是,您的查询输出是:
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
| mycount | st | group_number | tmp_interv | id | start_date | end_date | some_text | cnt |
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
| 2 | 2015-09-14 12:00:05 | 0 | 2015-09-14 12:00:05 | 1 | 2015-09-14 12:00:00 | 2015-09-14 12:00:00 | some | 1 |
| 4 | 2015-09-14 12:00:05 | 1 | 2015-09-14 12:01:08 | 3 | 2015-09-14 12:01:03 | 2015-09-14 12:01:03 | some | 1 |
| 1 | 2015-09-14 12:01:08 | 2 | 2015-09-14 12:01:14 | 7 | 2015-09-14 12:01:09 | 2015-09-14 12:01:09 | some | 1 |
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
但它应该是这样的:
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
| mycount | st | group_number | tmp_interv | id | start_date | end_date | some_text | cnt |
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
| 2 | 2015-09-14 12:00:05 | 0 | 2015-09-14 12:00:05 | 1 | 2015-09-14 12:00:00 | 2015-09-14 12:00:03 | some | 1 |
| 5 | 2015-09-14 12:00:05 | 1 | 2015-09-14 12:01:08 | 3 | 2015-09-14 12:01:03 | 2015-09-14 12:01:09 | some | 1 |
+---------+---------------------+--------------+---------------------+----+--------------------+----------------------+-----------+------+
注意计数和 date_end :)
这是我的第一次尝试:
CREATE TABLE `dtable` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`start_date` timestamp NULL DEFAULT NULL,
`end_date` timestamp NULL DEFAULT NULL,
`some_text` varchar(32) DEFAULT NULL,
`cnt` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
INSERT INTO `dtable` (`id`, `start_date`, `end_date`, `some_text`, `cnt`)
VALUES
(1, '2015-09-14 12:00:00', '2015-09-14 12:00:00', 'some', 1),
(2, '2015-09-14 12:00:03', '2015-09-14 12:00:03', 'some', 1),
(3, '2015-09-14 12:01:03', '2015-09-14 12:01:03', 'some', 1),
(4, '2015-09-14 12:01:04', '2015-09-14 12:01:03', 'some', 1),
(5, '2015-09-14 12:01:05', '2015-09-14 12:01:03', 'some', 1),
(6, '2015-09-14 12:01:08', '2015-09-14 12:01:08', 'some', 1),
(7, '2015-09-14 12:01:09', '2015-09-14 12:01:09', 'some', 1);
SELECT sum(cnt) mycount, t.* FROM (
SELECT
@interval_end:=IF(@interval_end = 0, d.start_date + INTERVAL 5 SECOND, @interval_end ) st,
@group_nr:= IF( d.start_date > @interval_end, @group_nr:=@group_nr+1, @group_nr ) group_number,
@interval_end:= IF( d.start_date > @interval_end, d.start_date + INTERVAL 5 SECOND , @interval_end ) tmp_interv,
d.* FROM dtable d,(SELECT @group_nr:=0, @interval_end:=0) tmp
) AS t
GROUP BY t.group_number;
请检查并指出有什么问题
我找到了解决方案,比你多得多 Bernd,我为了我的目的修改了你的查询:
SELECT
sum(cnt) mycount, t.start_date, max(t.start_date) date_end, t.* FROM (
SELECT
@interval_end:=IF(@interval_end = 0, d.start_date + INTERVAL 5 SECOND, @interval_end ) st,
@group_nr:= IF( d.start_date > @interval_end, @group_nr:=@group_nr+1, @group_nr ) group_number,
@interval_end:= IF( d.start_date > @interval_end, d.start_date + INTERVAL 5 SECOND , d.start_date + INTERVAL 5 SECOND) tmp_interv,
d.* FROM dtable d,(SELECT @group_nr:=0, @interval_end:=0) tmp
) AS t
GROUP BY t.group_number;
我有一个历史日志,我想总结一些条目。间隔应该是5秒
例如: 我有一个列表
date_start | date_end | count | somestring
2015-09-15 12:04:09 | 2015-09-15 12:04:09| 1 | xyz
2015-09-15 12:05:09 | 2015-09-15 12:05:09| 1 | xyz
2015-09-15 12:05:10 | 2015-09-15 12:05:10| 1 | xyz
2015-09-15 12:05:11 | 2015-09-15 12:05:11| 1 | xyz
2015-09-15 12:06:09 | 2015-09-15 12:06:09| 1 | xyz
我现在想要一个像
这样的输出date_start | date_end | count | somestring
2015-09-15 12:04:09 | 2015-09-15 12:04:09| 1 | xyz
2015-09-15 12:05:09 | 2015-09-15 12:05:11| 3 | xyz <--
2015-09-15 12:06:09 | 2015-09-15 12:06:09| 1 | xyz
因此,如果在 5 秒的间隔内出现重复,我想将其归为一个条目。但如果 1 小时内有多个条目,每个最大值。相隔 5 秒我也想把所有这些条目数一遍。
有人知道办法吗?我已经为此工作了几个星期了:(
编辑: 对 Bernd 的回答和评论: 非常感谢,您的查询输出为: 谢谢@Bernd。问题是,您的查询输出是:
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
| mycount | st | group_number | tmp_interv | id | start_date | end_date | some_text | cnt |
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
| 2 | 2015-09-14 12:00:05 | 0 | 2015-09-14 12:00:05 | 1 | 2015-09-14 12:00:00 | 2015-09-14 12:00:00 | some | 1 |
| 4 | 2015-09-14 12:00:05 | 1 | 2015-09-14 12:01:08 | 3 | 2015-09-14 12:01:03 | 2015-09-14 12:01:03 | some | 1 |
| 1 | 2015-09-14 12:01:08 | 2 | 2015-09-14 12:01:14 | 7 | 2015-09-14 12:01:09 | 2015-09-14 12:01:09 | some | 1 |
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
但它应该是这样的:
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
| mycount | st | group_number | tmp_interv | id | start_date | end_date | some_text | cnt |
+---------+---------------------+--------------+---------------------+----+---------------------+---------------------+-----------+------+
| 2 | 2015-09-14 12:00:05 | 0 | 2015-09-14 12:00:05 | 1 | 2015-09-14 12:00:00 | 2015-09-14 12:00:03 | some | 1 |
| 5 | 2015-09-14 12:00:05 | 1 | 2015-09-14 12:01:08 | 3 | 2015-09-14 12:01:03 | 2015-09-14 12:01:09 | some | 1 |
+---------+---------------------+--------------+---------------------+----+--------------------+----------------------+-----------+------+
注意计数和 date_end :)
这是我的第一次尝试:
CREATE TABLE `dtable` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`start_date` timestamp NULL DEFAULT NULL,
`end_date` timestamp NULL DEFAULT NULL,
`some_text` varchar(32) DEFAULT NULL,
`cnt` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
INSERT INTO `dtable` (`id`, `start_date`, `end_date`, `some_text`, `cnt`)
VALUES
(1, '2015-09-14 12:00:00', '2015-09-14 12:00:00', 'some', 1),
(2, '2015-09-14 12:00:03', '2015-09-14 12:00:03', 'some', 1),
(3, '2015-09-14 12:01:03', '2015-09-14 12:01:03', 'some', 1),
(4, '2015-09-14 12:01:04', '2015-09-14 12:01:03', 'some', 1),
(5, '2015-09-14 12:01:05', '2015-09-14 12:01:03', 'some', 1),
(6, '2015-09-14 12:01:08', '2015-09-14 12:01:08', 'some', 1),
(7, '2015-09-14 12:01:09', '2015-09-14 12:01:09', 'some', 1);
SELECT sum(cnt) mycount, t.* FROM (
SELECT
@interval_end:=IF(@interval_end = 0, d.start_date + INTERVAL 5 SECOND, @interval_end ) st,
@group_nr:= IF( d.start_date > @interval_end, @group_nr:=@group_nr+1, @group_nr ) group_number,
@interval_end:= IF( d.start_date > @interval_end, d.start_date + INTERVAL 5 SECOND , @interval_end ) tmp_interv,
d.* FROM dtable d,(SELECT @group_nr:=0, @interval_end:=0) tmp
) AS t
GROUP BY t.group_number;
请检查并指出有什么问题
我找到了解决方案,比你多得多 Bernd,我为了我的目的修改了你的查询:
SELECT
sum(cnt) mycount, t.start_date, max(t.start_date) date_end, t.* FROM (
SELECT
@interval_end:=IF(@interval_end = 0, d.start_date + INTERVAL 5 SECOND, @interval_end ) st,
@group_nr:= IF( d.start_date > @interval_end, @group_nr:=@group_nr+1, @group_nr ) group_number,
@interval_end:= IF( d.start_date > @interval_end, d.start_date + INTERVAL 5 SECOND , d.start_date + INTERVAL 5 SECOND) tmp_interv,
d.* FROM dtable d,(SELECT @group_nr:=0, @interval_end:=0) tmp
) AS t
GROUP BY t.group_number;