要根据给定数据填充表(SQL Server):
StartData-04/1/2019,EndData-04/30/2019,Interval = 2
根据间隔跳过一周。就像显示的预期结果一样。
输出:
04/01/2019
04/02/2019
04/03/2019
04/04/2019
04/05/2019
04/06/2019
04/07/2019
** Skip 7 days
04/15/2019
04/16/2019
04/17/2019
04/18/2019
04/19/2019
04/20/2019
04/21/2019
** Skip 7 days
04/29/2019
04/30/2019
答案 0 :(得分:2)
使用从零开始的计数表,这非常简单。
DECLARE @StartDate date = '20190401',
@EndDate date = '20190430',
@interval int = 2;
WITH
E(n) AS(
SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
),
E2(n) AS(
SELECT a.n FROM E a, E b
),
E4(n) AS(
SELECT a.n FROM E2 a, E2 b
),
cteTally(n) AS(
SELECT TOP(DATEDIFF( dd, @StartDate, @EndDate) + 1)
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) -1
FROM E4
)
SELECT DATEADD( DD, n, @StartDate)
FROM cteTally
WHERE (n/7 + 1)% @interval = 1;
当然可以将其转换为内联表值函数,以结合性能和易用性。
CREATE FUNCTION getDateListWithIntervals(
@StartDate date,
@EndDate date,
@interval int
)
RETURNS TABLE
AS RETURN
WITH
E(n) AS(
SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
),
E2(n) AS(
SELECT a.n FROM E a, E b
),
E4(n) AS(
SELECT a.n FROM E2 a, E2 b
),
cteTally(n) AS(
SELECT TOP(DATEDIFF( dd, @StartDate, @EndDate) + 1)
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) -1
FROM E4
)
SELECT DATEADD( DD, n, @StartDate) calDate
FROM cteTally
WHERE (n/7 + 1)% @interval = 1;
答案 1 :(得分:1)
使用CTE实现了此目的
with t0(i) as (select 0 union all select 0 union all select 0 union all select 0 union all select 0 union all select 0),
t1(i) as (select 0 from t0 a, t0 b),
n(i) as (select row_number()over(order by i) from t1),
tbl1 as ( select 0 i, dateadd(month, datediff(month,0,getdate()),0) daysOfMonth
union all
select n.i , dateadd(day,n.i, dateadd(month, datediff(month,0,getdate()),0)) daysOfMonth from n where n.i between 0 and 6 ),
tbl2 as (select n.i , dateadd(day,n.i, dateadd(month, datediff(month,0,getdate()),0)) daysOfMonth from n where n.i between datepart(day,dateadd(day,7,(select max(daysOfMonth) from tbl1))) and dateadd(day,7,datepart(day,dateadd(day,6,(select max(daysOfMonth) from tbl1))))),
tbl3 as (select n.i , dateadd(day,n.i, dateadd(month, datediff(month,0,getdate()),0)) daysOfMonth from n where n.i between datepart(day,dateadd(day,7,(select max(daysOfMonth) from tbl2))) and dateadd(day,-1,datepart(day,eomonth(getdate()))))
select * from tbl1
union all
select * from tbl2
union all
select * from tbl3
在上面的查询中,CTE表t0, t1 and n
用于生成数字。
表tbl
将获取该月的前7天。
表tbl2
将在接下来的7天中跳过,并在下周获取。这可以使用datediff
和dateadd
函数来完成。
表tbl3
将再次跳过7天,并将所有日期拉到月底。
输出
答案 2 :(得分:0)
删除-取消注释选择语句, 我已经打印了结果,您也可以选择。
DECLARE @StartDate datetime ='01-Apr-2019',
@EndDate datetime ='30-Apr-2019',
@Interval int = 2
DECLARE @dt datetime = @StartDate,
@count int = 1
WHILE (@dt <= @EndDate)
BEGIN
print @dt
--Select @dt
IF @count % 7 = 0
BEGIN
SET @Interval = @Interval - 1
SET @dt = dateAdd(day, 8, @dt);
PRINT '** Skip 7 days'
--SELECT '** Skip 7 days'
END
ELSE
BEGIN
SET @dt = dateAdd(day, 1, @dt);
END
SET @count = @count + 1
END
答案 3 :(得分:0)
使用上一个问题中提供的功能
示例
Declare @Date1 date = '2018-04-01'
Declare @Date2 date = '2018-04-30'
Declare @Freq int = 2
Declare @OffDays varchar(50) = 'Thursday' -- Try 'Saturday,Sunday'
Select B.RetVal
From [dbo].[tvf-Range-Date](@Date1,@Date2,'WK',1) A
Cross Apply [dbo].[tvf-Range-Date](A.RetVal,DateAdd(DAY,6,A.RetVal),'DD',1) B
Where A.RetSeq % @Freq = 1
and B.RetVal<=@Date2
返回
感兴趣的功能
CREATE FUNCTION [dbo].[tvf-Range-Date] (@R1 datetime,@R2 datetime,@Part varchar(10),@Incr int)
Returns Table
Return (
with cte0(M) As (Select 1+Case @Part When 'YY' then DateDiff(YY,@R1,@R2)/@Incr When 'QQ' then DateDiff(QQ,@R1,@R2)/@Incr When 'MM' then DateDiff(MM,@R1,@R2)/@Incr When 'WK' then DateDiff(WK,@R1,@R2)/@Incr When 'DD' then DateDiff(DD,@R1,@R2)/@Incr When 'HH' then DateDiff(HH,@R1,@R2)/@Incr When 'MI' then DateDiff(MI,@R1,@R2)/@Incr When 'SS' then DateDiff(SS,@R1,@R2)/@Incr End),
cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a, cte1 b, cte1 c, cte1 d, cte1 e, cte1 f, cte1 g, cte1 h ),
cte3(N,D) As (Select 0,@R1 Union All Select N,Case @Part When 'YY' then DateAdd(YY, N*@Incr, @R1) When 'QQ' then DateAdd(QQ, N*@Incr, @R1) When 'MM' then DateAdd(MM, N*@Incr, @R1) When 'WK' then DateAdd(WK, N*@Incr, @R1) When 'DD' then DateAdd(DD, N*@Incr, @R1) When 'HH' then DateAdd(HH, N*@Incr, @R1) When 'MI' then DateAdd(MI, N*@Incr, @R1) When 'SS' then DateAdd(SS, N*@Incr, @R1) End From cte2 )
Select RetSeq = N+1
,RetVal = D
From cte3,cte0
Where D<=@R2
)
/*
Max 100 million observations -- Date Parts YY QQ MM WK DD HH MI SS
Syntax:
Select * from [dbo].[tvf-Range-Date]('2016-10-01','2020-10-01','YY',1)
Select * from [dbo].[tvf-Range-Date]('2016-01-01','2017-01-01','MM',1)
*/