create table #temp (date date)
declare @X date
set @X = '2016-7-01'
declare @Y date
set @Y = cast (getdate() as date)
while(@X<=@Y)
begin
if (datename(WEEKDAY,@X) = 'Sunday')
insert into #temp values (@X)
set @X = cast(((cast(@X as datetime))+1)as date)
continue
end
select * from #temp
drop table #temp
是否可以使用CTE递归编写上述查询?
答案 0 :(得分:1)
您可以使用CTE创建数字表。然后,您可以使用数字表来获取日期:
Declare @Startdate Datetime = '2016-07-01'
Declare @EndDate Datetime = '2016-08-29'
;with
N0 as (SELECT 1 as n UNION ALL SELECT 1)
,N1 as (SELECT 1 as n FROM N0 t1, N0 t2)
,N2 as (SELECT 1 as n FROM N1 t1, N1 t2)
,N3 as (SELECT 1 as n FROM N2 t1, N2 t2)
,N4 as (SELECT 1 as n FROM N3 t1, N3 t2)
,nums as (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as num FROM N4)
SELECT DATEADD(day,num-1,@startdate) as thedate
FROM nums
WHERE num <= DATEDIFF(day,@startdate,@enddate) + 1
and datename(WEEKDAY, DATEADD(day,num-1,@startdate)) = 'Sunday'
每个表格(N0
到nums
)有效地将前一个“表格”中的行数相乘,因此您最终会在nums
中找到65,536行数字(您可以执行此操作)通过根据需要添加或删除表NX
来减少或更多。然后,使用数字表将天数添加到开始日期(SELECT DATEADD(day,num-1,@startdate) as thedate
),其中返回的日期位于您的日期范围内,weekday
为星期日。
此外,由于nums
中的数字从1开始,我们在选择中使用nums-1
,以避免跳过我们系列中的第一个日期,从而有效地为我们DATEADD(day, 0, @startdate)
在我们的第一排。
答案 1 :(得分:0)
你可以尝试这里解释的内容:http://blog.sqlauthority.com/2009/12/29/sql-server-get-date-of-all-weekdays-or-weekends-of-the-year/
DECLARE @StartDate DATETIME
DECALRE @EndDate DATETIME
SET @StartDate = '2016-07-01'
SET @EndDate = GETDATE()
;WITH cte AS (
SELECT
1 AS DayID,
@StartDate AS FromDate,
DATENAME(dw, @StartDate) AS Dayname
UNION ALL
SELECT
cte.DayID + 1 AS DayID,
DATEADD(d, 1, cte.FromDate),
DATENAME(dw, DATEADD(d, 1, cte.FromDate)) AS Dayname
FROM cte
WHERE DATEADD(d, 1, cte.FromDate) < @EndDate
)
SELECT FromDate AS Date, Dayname
FROM cte
WHERE Dayname IN ('Sunday')
我认为通过使用数字表和7倍(取决于您需要获得多少日期,可能预先计算第一个星期日),这是一种更有效的方法从你的开始日期开始,然后从数字表中加入所有数字7的数字),但上面的效果也很好。
答案 2 :(得分:0)
;with cte
as
(
select getdate() as datee
union all
select dateadd(day,1,datee)
from cte
where datediff(day,getdate(),datee)<100
)
select * from cte
where datename(WEEKDAY,datee) = 'Sunday'
你也会达到最大递归限制,以避免..使用类似下面的东西..
option ( MaxRecursion 0 )
如果我不受使用递归cte的限制,我会使用数字表来解决这个问题,这也比Recursive cte快..
select
dateadd(day,n,getdate()) as datee
from numbers
where n<100 and datename(weekday,dateadd(day,n,getdate()))='sunday'
要了解您需要数字表的原因,请查看此链接.. https://dba.stackexchange.com/questions/11506/why-are-numbers-tables-invaluable