Sql 生成15分钟的日期间隔并连接匹配的行
我想做的是根据一行中的日期范围获得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'
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;