Sql 生成15分钟的日期间隔并连接匹配的行

Sql 生成15分钟的日期间隔并连接匹配的行,sql,sql-server,tsql,datetime,Sql,Sql Server,Tsql,Datetime,我想做的是根据一行中的日期范围获得15分钟的间隔,并将它们插入另一个表中 以下代码为我提供了日期范围,这是我目标的一部分: DECLARE @Table1 TABLE (ID INT IDENTITY(0,1), TIMEVALUE DATETIME, TIMEVALUE2 DATETIME); DECLARE @start DATETIME2(7) = '2018-01-04 10:55:00' DECLARE @end DATETIME2(7) = '2018-01-05 03:55:00'

我想做的是根据一行中的日期范围获得15分钟的间隔,并将它们插入另一个表中

以下代码为我提供了日期范围,这是我目标的一部分:

DECLARE @Table1 TABLE (ID INT IDENTITY(0,1), TIMEVALUE DATETIME, TIMEVALUE2 DATETIME);
DECLARE @start DATETIME2(7) = '2018-01-04 10:55:00'
DECLARE @end DATETIME2(7) = '2018-01-05 03:55:00'
SELECT  @start = dateadd(minute, datediff(minute,0,@start) / 15 * 15, 0);

WITH CTE_DT AS 
(
    SELECT @start AS DT
    UNION ALL
    SELECT DATEADD(MINUTE,15,DT) FROM CTE_DT
    WHERE DT< @end
)
INSERT INTO @Table1
SELECT DT, DATEADD(minute,14,dt) FROM CTE_DT
OPTION (MAXRECURSION 0);

SELECT * FROM @Table1    
我想要实现的是从记录源应用与我相同的逻辑

所以如果我的SourceData是

Col1    Col2    StartDate           EndDate
AA      AA      2018-01-01 13:25    2018-01-02 13:00
AA      BB      2018-01-02 13:25    2018-01-03 13:00
因此,对于一个查询,可以使用start和endate来生成一个查询结果

Col1    Col2    TIMEVALUE       TIMEVALUE2
AA      AA  2018-01-01 13:15:00 2018-01-01 13:29:00
AA      AA  2018-01-01 13:30:00 2018-01-01 13:44:00
AA      AA  2018-01-01 13:45:00 2018-01-01 13:59:00
...
...
AA      AA  2018-01-02 12:30:00 2018-01-02 12:44:00
AA      AA  2018-01-02 12:45:00 2018-01-02 12:59:00
AA      AA  2018-01-02 13:00:00 2018-01-02 13:14:00
AA      BB  2018-01-02 13:15:00 2018-01-02 13:29:00
AA      BB  2018-01-02 13:30:00 2018-01-02 13:44:00
AA      BB  2018-01-02 13:45:00 2018-01-02 13:59:00
...
...
AA      BB  2018-01-03 12:30:00 2018-01-03 12:44:00
AA      BB  2018-01-03 12:45:00 2018-01-03 12:59:00
AA      BB  2018-01-03 13:00:00 2018-01-03 13:14:00

如果可以,我希望避免使用光标。通过使用select语句传递所需的列,我成功地使用用户定义的函数实现了这一点。如果可以的话,我希望可以避免使用该选项。

更改第一个查询的结尾,以便

SELECT * FROM @Table1  
它说:

SELECT * FROM @Table1 d 
INNER JOIN SourceData sd 
ON NOT(d.timevalue2 < sd.startdate OR d.timevalue1 > sd.enddate)
从@table1d中选择*
内部连接SourceData sd
ON NOT(d.timevalue2sd.enddate)
考虑使用第一个生成日期的查询,现在就运行它,直到2030年,然后将日期插入到实际的表中。保持查询挂起,以便在大约11年后再次使用它向日历表添加更多行,而不是使用rCTE(RBAR的一种形式),我将使用虚拟理货表生成日期:

--; is a statement terminator, not a "beginninator". It goes at the end, for the start.
WITH N AS(
    SELECT NULL AS N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS (
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
    FROM N N1 --10
         CROSS JOIN N N2 --100
         CROSS JOIN N N3 --1000
         CROSS JOIN N N4 --10000
    )
SELECT DATEADD(MINUTE,15*I,@Start)
FROM Tally
WHERE DATEADD(MINUTE,15*I,@Start) < @End;

谢谢,我想我会走这条路。我在想如何使用stackoverflow时,按错了回车键。一开始有点痛。谢谢你的邀请solution@deswal ? 我不知道你说的是什么意思。当我最初发布这篇文章时,我不明白编辑是如何工作的。我可能只是在错误的位置添加了一个
。提示:使用a可以避免试图拨弄时间间隔,例如
intervals开始感谢各位的建议
--; is a statement terminator, not a "beginninator". It goes at the end, for the start.
WITH N AS(
    SELECT NULL AS N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS (
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
    FROM N N1 --10
         CROSS JOIN N N2 --100
         CROSS JOIN N N3 --1000
         CROSS JOIN N N4 --10000
    )
SELECT DATEADD(MINUTE,15*I,@Start)
FROM Tally
WHERE DATEADD(MINUTE,15*I,@Start) < @End;
--Assume CTEs are already declared
SELECT V.Col1, V.Col2,
       DATEADD(MINUTE,15*T.I,@Start)
FROM Tally T
     CROSS JOIN (VALUES('AA','AA'),('AA','BB')) V(Col1, Col2) --This could be a CROSS APPLY to a DISTINCT, or similar is you wish
WHERE DATEADD(MINUTE,15*T.I,@Start) < @End;