每分钟在范围之间添加行
For each minute add row between ranges
我有 table 日期范围
我需要在此范围之间添加行。我必须将这个 table 细化到几分钟。我如何添加这些额外的行
如果您使用以下内容:
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
选项(最大递归 0)
它会给你一分钟一分钟的结果。在你想要的范围内替换。然后,您可以以此为基础编写插入内容。迭代 CTE 不是最有效的,但可能是最简单的
来自@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 服务器以递归方式生成超过默认值 100 的分钟数。不过,如果生成的时间间隔超过几百分钟,我不建议这样做(最多一天 [1440 分钟]).
在这种情况下,更简单的方法是使用 table 个数字,然后简单地加入它。
创建这样一个 table 的示例可以是: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 秒获取数据怎么办?那是在一分钟结束之后但在新一分钟开始之前?而是使用 Inclusive Start 和 Exclusive End 的标记...
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
。)
我有 table 日期范围
我需要在此范围之间添加行。我必须将这个 table 细化到几分钟。我如何添加这些额外的行
如果您使用以下内容:
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
选项(最大递归 0)
它会给你一分钟一分钟的结果。在你想要的范围内替换。然后,您可以以此为基础编写插入内容。迭代 CTE 不是最有效的,但可能是最简单的
来自@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 服务器以递归方式生成超过默认值 100 的分钟数。不过,如果生成的时间间隔超过几百分钟,我不建议这样做(最多一天 [1440 分钟]).
在这种情况下,更简单的方法是使用 table 个数字,然后简单地加入它。
创建这样一个 table 的示例可以是: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 秒获取数据怎么办?那是在一分钟结束之后但在新一分钟开始之前?而是使用 Inclusive Start 和 Exclusive End 的标记...
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
。)