查询:
SELECT project_id,
COUNT(*) AS count,
MIN(date_added) AS date_start,
MAX(date_added) AS date_end
FROM my_table
GROUP BY project_id, TIMESTAMPDIFF(MINUTE, date_added) < 5
WHERE user_id = 1 LIMIT 10
我怎样才能做到这一点?我想对项目进行分组,以便组中没有两个连续项目相隔超过5分钟,但开始和结束时间可以相隔任何距离。有没有办法在数据库中执行此操作,或者我是否需要获取所有数据并在程序中找到它?
答案 0 :(得分:3)
好的,这里有:
SELECT id, project_id, start_time, MAX(end_time) AS end_time FROM (
SELECT
@new_group :=
((TIME_TO_SEC(date_added) - @prev_second) > (5 * 60)) ||
(project_id <> @prev_project_id) AS new_group,
@date_added_group := @date_added_group + @new_group AS date_added_group,
@start_time := IF(@new_group, date_added, @start_time) AS start_time,
id,
project_id,
date_added AS end_time,
@prev_second := TIME_TO_SEC(date_added) AS prev_sec,
@prev_project_id := project_id AS prev_project
FROM my_table,
(SELECT
@new_group :=0,
@date_added_group := 0,
@start_time := 0,
@prev_second := 0,
@prev_project_id := 0) AS vars
ORDER BY project_id, date_added
) AS my_table GROUP BY project_id, date_added_group;
鉴于此数据:
+----+------------+---------------------+
| id | project_id | date_added |
+----+------------+---------------------+
| 1 | 1 | 2010-07-15 19:00:00 | < new project
| 2 | 1 | 2010-07-15 19:01:00 |
| 3 | 1 | 2010-07-15 19:02:00 |
| 4 | 2 | 2010-07-15 19:03:00 | < new project
| 5 | 2 | 2010-07-15 19:04:00 |
| 6 | 2 | 2010-07-15 19:25:00 | < new interval
| 7 | 2 | 2010-07-15 19:26:00 |
| 8 | 2 | 2010-07-15 19:27:00 |
| 9 | 2 | 2010-07-15 19:48:00 | < new interval
| 10 | 2 | 2010-07-15 19:49:00 |
| 11 | 3 | 2010-07-15 19:50:00 |
| 12 | 3 | 2010-07-15 20:11:00 | < new interval
| 13 | 4 | 2010-07-15 20:12:00 | < new project
| 14 | 4 | 2010-07-15 20:13:00 |
| 15 | 4 | 2010-07-15 20:14:00 |
| 16 | 5 | 2010-07-15 20:15:00 | < new project
| 17 | 5 | 2010-07-15 20:16:00 |
| 18 | 5 | 2010-07-15 21:27:00 | < new interval
| 19 | 5 | 2010-07-15 21:28:00 |
| 20 | 6 | 2010-07-15 21:29:00 | < new project
| 21 | 6 | 2010-07-15 21:30:00 |
| 22 | 6 | 2010-07-15 21:31:00 |
+----+------------+---------------------+
查询返回此结果集:
+----+------------+---------------------+---------------------+
| id | project_id | start_time | end_time |
+----+------------+---------------------+---------------------+
| 1 | 1 | 2010-07-15 19:00:00 | 2010-07-15 19:02:00 |
| 4 | 2 | 2010-07-15 19:03:00 | 2010-07-15 19:04:00 |
| 6 | 2 | 2010-07-15 19:25:00 | 2010-07-15 19:27:00 |
| 9 | 2 | 2010-07-15 19:48:00 | 2010-07-15 19:49:00 |
| 11 | 3 | 2010-07-15 19:50:00 | 2010-07-15 19:50:00 |
| 12 | 3 | 2010-07-15 20:11:00 | 2010-07-15 20:11:00 |
| 13 | 4 | 2010-07-15 20:12:00 | 2010-07-15 20:14:00 |
| 16 | 5 | 2010-07-15 20:15:00 | 2010-07-15 20:16:00 |
| 18 | 5 | 2010-07-15 21:27:00 | 2010-07-15 21:28:00 |
| 20 | 6 | 2010-07-15 21:29:00 | 2010-07-15 21:31:00 |
+----+------------+---------------------+---------------------+
答案 1 :(得分:2)
在我的头顶,我没有尝试:
SELECT project_id,
COUNT(*) AS count,
MIN(date_added) AS date_start,
MAX(date_added) AS date_end
FROM my_table
WHERE user_id = 1
GROUP BY project_id, ROUND(date_added / (5 * 60))
LIMIT 10
当然,假设在几秒钟内“注明日期”。
换句话说,项目根据它们所属的5分钟切片进行分组。
答案 2 :(得分:0)
由于您希望将最长的记录链连接在一起,每对记录的间距小于5分钟,我认为您无法使用GROUP BY
执行此操作。
尝试使用WHILE loop编写存储过程。从一个选择记录ORDER BY date_added
的游标开始。您可以创建TEMPORARY TABLE并在每个组的末尾插入一行。通过将其作为存储过程,您可以避免将所有记录拉回到您的程序中(通常通过网络),这可以使它更快。