提问人:Paul-Marie 提问时间:11/7/2023 更新时间:11/8/2023 访问量:41
如何对列列表进行分组,每个 2 个元素
How to group a column list each 2 elements
问:
我请求按升序排序的列表,例如: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.999
838:59:59.999
评论