答案 0 :(得分:1)
来自@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的分钟。但是,如果生成的间隔超过几百分钟,我不建议这样做。到一天[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
。)
答案 1 :(得分:0)
如果您使用以下内容:
WITH cte
AS (SELECT CAST('2017-01-01 00:00:00' AS DATETIME) AS startTime
UNION ALL
SELECT DATEADD(MINUTE, 1, startTime)
FROM cte
WHERE startTime < '2017-01-02 00:00:00'
)
SELECT *
FROM cte
选项(MAXRECURSION 0)
它会给你一分钟的结果。替换你想要的范围。然后,您可以将其用作编写插入的基础。迭代CTE不是最有效的,但可能是最简单的