我有一个这样的表(为简化起见,删除了其他列):
Serial | Start_Datetime
---------------------------------
5139970 | 2019-12-12 16:32:14
5139970 | 2020-01-18 05:42:50
5134473 | 2020-02-23 14:28:10
5134473 | 2020-02-23 21:07:49
5134473 | 2020-02-25 13:56:30
我需要在列表中重复序列时,以天,小时,分钟和秒为单位计算日期差。序列号没有任何相关性或顺序,但日期的顺序是从最旧的顶部到最后的底部。
预期结果应如下所示:
Serial | Start_Datetime | Date_Diff
----------------------------------------------------------------------------
5139970 | 2019-12-12 16:32:14 | Null
5139970 | 2020-01-18 05:42:50 | 36 days 13 hours 10 minutes 36 seconds
5134473 | 2020-02-23 14:28:10 | Null
5134473 | 2020-02-23 21:07:49 | 0 days 6 hours 39 minutes 39 seconds
5134473 | 2020-02-25 13:56:30 | 1 day 16 hours 48 minutes 41 second
在MySQL 8中,可以使用lag
在结果“窗口”中获取上一行。
每个窗口的“框架”是序列号,由start_datetime排序。
lag
要准确获得所需的格式,select
serial,
start_datetime,
-- To demonstrate what value lag() is.
lag(start_datetime, 1) over w as prev_start_datetime,
timediff(
start_datetime,
lag(start_datetime, 1) over w
) as date_diff
from the_table
window w as (
partition by serial
order by start_datetime asc
)
order by serial desc, start_datetime asc;
。
如果您未使用MySQL 8,强烈建议您进行升级。它增加了很多很棒的新功能。如果无法升级,请see these answers。
在mysql 5.x中,您可以使用用户定义的变量来完成但这比mysql 8版本要难看得多。datediff的位置必须首先位于,以便它可以工作
在您的应用程序中,您可以根据需要订购它
use these work aroundsDate_Diff |系列|开始时间:----------------- | ------:| :------------------空 | 5134473 | 2020-02-23 14:28:100days 6h:39m:39s | 5134473 | 2020-02-23 21:07:491days 16h:48m:41s | 5134473 | 2020-02-25 13:56:30空 | 5139970 | 2019-12-12 16:32:1434days 22h:59m:59s | 5139970 | 2020-01-18 05:42:50
db <>小提琴SELECT
IF(@id = `Serial`, CONCAT(
FLOOR(TIME_FORMAT(SEC_TO_TIME(TO_SECONDS( `Start_Datetime`) - TO_SECONDS(@OLDdate)), '%H') / 24), 'days ',
MOD(TIME_FORMAT(SEC_TO_TIME(TO_SECONDS( `Start_Datetime`) - TO_SECONDS(@OLDdate)), '%H'), 24), 'h:',
TIME_FORMAT(SEC_TO_TIME(TO_SECONDS( `Start_Datetime`) - TO_SECONDS(@OLDdate)), '%im:%ss')
), NULL) Date_Diff,
@id := `Serial` 'serial',
@OLDdate := `Start_Datetime` 'Start_Datetime'
FROM
(SELECT * FROM mytable ORDER BY `Serial`, `Start_Datetime`) t1,(SELECT @id := 0) t2,(SELECT @OLDdate := NOW()) t3;