【问题标题】:Generate time serie between time interval with steps of minutes on the fly in SQL在 SQL 中动态生成时间间隔之间的时间序列,步长为分钟
【发布时间】:2020-09-02 18:48:13
【问题描述】:

问题在文末。

我找到了这个链接来生成日期 Generating a series of dates 并修改它以生成时间间隔:

SET @start_time = "08:02";
SET @stop_time  = "17:02";
SELECT
     TIME_FORMAT(time(CONCAT(m3, m2, ':', m1, m0)) , "%H:%i") as Time
FROM
    (SELECT 0 m0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS m0,
    (SELECT 0 m1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS m1,
    (SELECT 0 m2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS m2,
    (SELECT 0 m3 UNION SELECT 1 UNION SELECT 2) AS m3
where time(CONCAT(m3, m2, ':', m1, m0)) is not null 
and time(CONCAT(m3, m2, ':', m1, m0)) >= @start_time
and time(CONCAT(m3, m2, ':', m1, m0)) <= @stop_time
order by Time asc

这将生成这个表:

Time
10:02
10:03
10:04
10:05
10:06
...
16:59
17:00
17:01

问题?

这可以写成更有效的方式吗?我想指定一个带步骤的间隔,因此可以快速将其更新为每 X 分钟间隔。我不想将结果存储在数据库中,我只想动态生成它。因为我会把它和其他表一起加入。

我在 mysql 查询中经常使用它来为易于在 Excel 中绘制的测量值创建时间序列。

【问题讨论】:

  • 我个人认为将它存储在数据库中是一个合理的论据,作为一个有 1440 行的表,一个时间列,可能还有一个小时列和分钟列,那么你可以这样做,例如 @987654325 @(或 MOD(MINUTE(time), 5),如果没有分隔的分钟列)得到例如“每 5 分钟,时间以 0 / 5 结尾”。数据库非常擅长查询表;他们做了很多..
  • 我只有一个只读帐户,而且我的时间序列通常很短,通常只有不到一个小时。我在这个例子中把它加长了,所以解决方案应该更通用。
  • 你必须走一段合理的距离才能找到一个 DBA,他主张每天动态生成 X 行 Y 次,而不是在表中包含少量行并选择它们,我认为.. 只读限制是一根大棒,而不是低行数是胡萝卜
  • 添加大量临时表会污染数据库。这就是他们从只读帐户开始的原因,因为大多数用户在他们自己之后不擅长清理。
  • 这不是临时表,而是永久表;询问接下来的 10 位 DBA,您会看到他们对日历和数字表的看法。它们可能比您想象的更普遍,而且它们很有意义,尤其是日历表,因为它们可以告诉您日期系列公式化生成无法告诉您的事情,例如公共假期

标签: mysql sql time query-optimization recursive-query


【解决方案1】:

为此,我非常喜欢递归 CTE:

with recursive times as (
      select time('10:00:00') as time
      union all
      select time + interval 17 minute
      from times
      where time < time('17:00:00')
     )
select *
from times;

Here 是一个 dbfiddle。

【讨论】:

  • 在 OP 的 MySQL 中肯定可用吗?
  • 谢谢,这比我的解决方案简单得多。
  • @banankontakt 。 . .从递归 CTE 的文档开始:dev.mysql.com/doc/refman/8.0/en/…
猜你喜欢
  • 2012-07-23
  • 1970-01-01
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 2012-05-28
  • 1970-01-01
相关资源
最近更新 更多