1

我有一张这样的桌子:

---------------------------------------------
|Id | Step                  | StartedAt     |
---------------------------------------------
| 1 | Download Data         | 10:20:00      |
| 2 | Data Quality Control  | 10:45:00      |
| 3 | Run Prediction        | 10:47:00      |
---------------------------------------------

什么是 SQL 查询,它告诉我每个步骤的时间,如下所示:“下载数据”需要 25 分钟,“数据质量控制”需要 2 分钟等等。

干杯。

PS我的RDBMS是MySQL。有没有办法在 MySQL 中做到这一点?

4

1 回答 1

0

您应该使用datetimeortimestamp而不是time使这项工作跨越日期边界。看评论。

大多数 RDBMS 的标准 SQL

为此使用窗口函数。目前已在最著名的 RDBMS(MySQL 除外)中实现:

SELECT *
     ,lead("StartedAt") OVER (ORDER BY "StartedAt") - "StartedAt" AS duration
FROM  tbl;

lead()根据子句中的顺序检索下一行的值。ORDER BY对于没有“下”行的最后一行,您得到NULL.

我引用了PostgreSQL 关于窗口函数的手册,因为您没有命名您的 RDBMS。

MySQL

在没有窗口函数的情况下,一种方法是使用相关子查询:

SELECT t1.*
     ,(SELECT t2."StartedAt"
       FROM tbl t2
       WHERE t2.id > t1.id
       ORDER BY t2."StartedAt"
       LIMIT 1) - "StartedAt" AS duration
FROM  tbl t1;

或者这可能更快:

SELECT t1."Id", t1."Step", t1."StartedAt"
      ,TIMESTAMPDIFF(MINUTE, t1."StartedAt", min(t2."StartedAt")) AS minutes
FROM   tbl t1
LEFT   JOIN tbl t2 ON t2."Id" > t1."Id"
GROUP  BY t1."Id", t1."Step", t1."StartedAt";

-> sqlfiddle 与两个查询。

手册关于TIMESTAMPDIFF()TIMEPDIFF()

如果您的Id列将上升而没有间隙,这会更简单。但在现实生活中这种情况很少见。

于 2012-12-06T23:52:11.307 回答