如何对列列表进行分组,每个 2 个元素

How to group a column list each 2 elements

提问人:Paul-Marie 提问时间:11/7/2023 更新时间:11/8/2023 访问量:41

问:

我请求按升序排序的列表,例如:DATETIME(3)

> SELECT occurred_at FROM events ORDER BY ASC;
+-------------------------+
| occurred_at             |
+-------------------------+
| 2023-11-07 10:21:34.517 |
| 2023-11-07 10:20:34.524 |
| 2023-11-07 10:19:34.514 |
| 2023-11-07 10:18:34.517 |
| 2023-11-07 10:17:34.512 |
| 2023-11-07 10:16:34.517 |
| 2023-11-07 10:15:34.518 |
| 2023-11-07 10:14:34.515 |
+-------------------------+

这个请求很简单,但我想测量每个日期之间的时间(意思是连续比较第一个结果和第二个结果之间的经过时间,然后是另一个结果中的第三个和第四个结果,等等......而不是比较第二个和第三个,第四个和第五个,等等...... 本机函数可以帮助我实现这个目标,但由于我的目标是将它们分组(也许使用?)按两个,我希望有一个如下所示的列表:TIMEDIFF(date1, date2)GROUP_CONCAT()

> THE_QUERY;
+---------------------------------------------------+
| occurred_at                                       |
+---------------------------------------------------+
| 2023-11-07 10:21:34.517, 2023-11-07 10:20:34.524 |
| 2023-11-07 10:19:34.514, 2023-11-07 10:18:34.517 |
| 2023-11-07 10:17:34.512, 2023-11-07 10:16:34.517 |
| 2023-11-07 10:15:34.518, 2023-11-07 10:14:34.515 |
+---------------------------------------------------+

或者更好的是,date1 和 date2 连续的结果,date3 和 date4 在另一个的结果,等等......TIMEDIFF()

由于我可以有很多行,因此我正在寻找使用模 2 和 co 的解决方案,但没有成功使其工作。

玛丽亚德 分组

评论


答:

1赞 slaakso 11/7/2023 #1

通常,您有一些信息,哪些行属于一起。但是,如果只想依赖列,则可以执行以下操作:

select min(occurred_at), max(occurred_at), timediff(max(occurred_at), min(occurred_at))
from (
  select occurred_at, cast((row_number() over (order by occurred_at))/2 as unsigned) as rn
  from events
)  as q 
group by rn desc
order by 1

查看 rn desc 的 dbfiddle 组 按 1 订购

评论

0赞 Paul-Marie 11/8/2023
不幸的是,此查询将向我显示最小日期和最大日期之间的时间差异,我想在其中显示第一个日期和第二个日期之间的时间差异,第三个日期与第四个日期,第五个日期和第六个日期之间的时间差异,等等......没有添加第二个和第三个,第四个和第五个,等等......所以它并没有真正回答我的问题
0赞 Paul-Marie 11/8/2023 #2

我终于设法通过这种查询实现了我的目标:

WITH data AS (
  SELECT occurred_at, ROW_NUMBER() OVER (ORDER BY occurred_at) AS row_num FROM `events`
)
SELECT
  CONCAT(a.occurred_at, ', ', b.occurred_at) AS occurred_at,
  TIMESTAMPDIFF(SECOND, a.occurred_at, COALESCE(b.occurred_at, NOW()))) AS amount
FROM data AS a LEFT JOIN data AS b
ON a.row_num = b.row_num - 1
WHERE a.row_num % 2 = 1;

请注意,处理不存在@b的情况非常重要,因为尚未发生关闭事件LEFT JOIN

所以我的最后一个查询,它将总结每个时间之间的所有时间,并将其作为小时返回,如下所示:events

WITH data AS (
  SELECT occurred_at, ROW_NUMBER() OVER (ORDER BY occurred_at) AS row_num FROM `events`
)
SELECT TRUNCATE(
  COALESCE(
    SUM(
      TIMESTAMPDIFF(SECOND, a.occurred_at, COALESCE(b.occurred_at, NOW()))
    ), 0) / (60 * 60), 2
) AS amount
FROM data AS a LEFT JOIN data AS b
ON a.row_num = b.row_num - 1
WHERE a.row_num % 2 = 1;

我使用 TIMESTAMPDIFF() 而不是 TIMEDIFF(),因为前者不受 TIME 类型的限制。 有了 你不能有大于小时的价值,如果你这样做,你仍然会得到警告。TIMEDIFF()838:59:59.999838:59:59.999