我需要从当前月份获取所有一周的开始和结束日期,假设我的一周从 星期六 开始并在 星期五 结束,我尝试过以下...
以下查询是表值函数的一部分,我在其中传递当前月份的开始日期并返回表运行时。
Declare @fromDate date
DECLARE @date date = GETUTCDATE()
DECLARE @tmpWeeks Table([WeekStart] date, [WeekEnd] date)
SET @fromDate = CAST(DATEADD(month, DATEDIFF(month, 0, @date), 0) as date)
;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, dates as (
select top (datediff(day, @fromdate, dateadd(month, datediff(month, 0, @fromdate )+1, 0))) [DateValue]=convert(date,dateadd(day,row_number() over(order by (select 1))-1,@fromdate))
from n as deka cross join n as hecto
)
Insert into @tmpWeeks
select
WeekStart = min(DateValue), WeekEnd = max(DateValue)
from dates
group by datepart(week,DateValue)
select * from @tmpWeeks
它给了我以下结果。
WeekStart WeekEnd
---------- ----------
2021-06-01 2021-06-04
2021-06-05 2021-06-11
2021-06-12 2021-06-18
2021-06-19 2021-06-25
2021-06-26 2021-06-30
<块引用>
以上结果部分正确,但是,如果我们看到这里第一条记录的 WeekStart
日期是 2021-06-01
但它应该有 2021-05-29
(周六)
同样,最后一条记录显示 WeekEnd
为
2021-06-30
但它应该有 2021-07-02
因此在考虑上述条件后,预期结果将如下所示..
WeekStart WeekEnd
---------- ----------
2021-05-29 2021-06-04
2021-06-05 2021-06-11
2021-06-12 2021-06-18
2021-06-19 2021-06-25
2021-06-26 2021-07-02
有什么帮助!?
答案 0 :(得分:1)
您可以使用这样的查询来实现:
declare @fromDate date = '06-02-2021'
set @fromDate =
case datepart(dw,@fromDate)
when 7 then @fromDate
else dateadd(day, - datepart(dw,@fromDate), @fromDate)
end
;with weeks as (
select datepart(week, @fromDate) w, @fromDate d, datepart(weekday, @fromDate) dd
union all
select datepart(week, dateadd(day, 1, d)), dateadd(day, 1, d), datepart(weekday, dateadd(day, 1, d)) from weeks where d <= '2022-01-01'
)
select dateadd(day, -1, min(d)) as weekstart, max(d) as weekend
from weeks
where dd in (1,6)
group by w
option (maxrecursion 0)
您可以在此 db<>fiddle
上进行测试递归 cte 可以很好地自动生成日期,就像您的情况一样。
答案 1 :(得分:1)
稍微调整了 OP 版本
Declare @fromDate date;
DECLARE @date date = GETUTCDATE();
declare @m int = month(@date);
-- -2 to shift start of week to Saturday
-- -5 to shift start to a previous month
SET @fromDate = DATEADD(week, DATEDIFF(week, 0, @date) - 5, 0) -2;
-- 11 weeks to cover month of interest fo sure
with t as (
select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) t(n) )
, dates as (
select [DateS] = dateadd(week, n, @fromdate)
from t
)
-- take current month only
select [DateS], dateadd(dd, 6, [DateS]) [DateE]
from dates
where @m in (month([DateS]), month(dateadd(dd, 6, [DateS])));