获取周开始和结束日期

时间:2021-06-16 07:18:22

标签: sql sql-server tsql

我需要从当前月份获取所有一周的开始和结束日期,假设我的一周从 星期六 开始并在 星期五 结束,我尝试过以下...

以下查询是表值函数的一部分,我在其中传递当前月份的开始日期并返回表运行时。

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 (周六)

同样,最后一条记录显示 WeekEnd2021-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

有什么帮助!?

2 个答案:

答案 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])));