【问题标题】:MySQL - Group on similar timestampsMySQL - 对类似时间戳进行分组
【发布时间】:2010-07-15 18:01:07
【问题描述】:

查询:

  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 分钟,但开始和结束时间可以相距任何距离。有没有办法在数据库中做到这一点,还是我需要抓取所有数据并在程序中计算出来?

【问题讨论】:

  • 一个有趣的问题 - 我期待看到这个问题的答案。

标签: mysql group-by aggregate-functions


【解决方案1】:

好的,开始吧:

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 |
+----+------------+---------------------+---------------------+

【讨论】:

    【解决方案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
    

    当然假设“dated_added”在几秒钟内。

    换句话说,项目是根据它们所属的 5 分钟切片进行分组的。

    【讨论】:

      【解决方案3】:

      由于您想将每对相隔不到 5 分钟的最长记录链链接在一起,我认为您无法使用 GROUP BY 做到这一点。

      尝试使用WHILE loop 编写存储过程。从选择记录ORDER BY date_added 的游标开始。您可以创建一个TEMPORARY TABLE 并在每个组的末尾插入一行。通过将其作为存储过程执行,您可以避免将所有记录拉回您的程序(通常通过网络),这可以使其更快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-19
        • 2015-03-07
        • 1970-01-01
        • 2011-01-31
        • 1970-01-01
        • 2014-01-03
        • 1970-01-01
        相关资源
        最近更新 更多