@MatthewBaker 的递归 CTE 选项只需稍作更改即可满足您的需求。
WITH
by_minute
AS
(
SELECT *, datetime_from, minute_marker FROM your_table
UNION ALL
SELECT *, DATEADD(minute, 1, minute_marker) FROM by_minute WHERE DATEADD(minute, 1, minute_marker) < datetime_to
)
SELECT
*
FROM
by_minute
OPTION
(MAXRECURSION 0)
OPTION (MAXRECURSION 0) 允许 SQL Server 继续递归生成超出默认值 100 的分钟数。不过,如果生成的时间间隔超过几百分钟,我不建议这样做(可能最多 1天 [1440 分钟]).
在这种情况下,更简单的方法是使用一个数字表,然后简单地加入它。
创建此类表的示例可能是:https://www.mssqltips.com/sqlservertip/4176/the-sql-server-numbers-table-explained--part-1/
从那里,您只需加入您需要的行数...
SELECT
yourTable.*,
DATEADD(minute, Numbers.[Number], yourTable.datetime_from) AS minute_marker
FROM
yourTable
INNER JOIN
dbo.Numbers
ON Numbers.[Number] >= 0
AND Numbers.[Number] < DATEDIFF(minute, yourTable.datetime_from, yourTable.datetime_to)
我的另一个建议是不要使用第 59 秒来表示一分钟的结束。如果您在 59.600 秒时获得数据怎么办?那是在那一分钟结束之后但在新一分钟开始之前?而是使用包含开始和排他结束的标记...
The first minute of 2012 = '2012-01-01 00:00:00.000' -> '2012-01-01 00:01:00.000'
The final minute of 2012 = '2012-12-31 23:59:00.000' -> '2013-01-01 00:00:00.000'
有了这样的结构,您只需要my_point_in_time >= start AND my_point_in_time < end,并且您无需担心所使用的数据类型的精度。
(它也匹配人类自然语言。当我们说between 1 and 2 之类的东西时,我们通常指的是>= 1 AND < 2。)