Home > database >  What is wrong with the code ? Please tell me what I am doing wrong
What is wrong with the code ? Please tell me what I am doing wrong

Time:10-14

This is my code

declare @startdate date='2021-01-01'
declare @enddate date='2021-12-31'
declare @week_end_date date

while (@startdate <= @enddate)
begin
    if (datepart(week, @startdate) = 1)
        select '01-01-2021'
    else
        set @startdate = DATEADD(day,1-datepart(dw,@startdate),@startdate)

    select @startdate week_start_date

    if (datepart(week, @startdate) = 53)
        select '2021-12-31' 
    else
        set @week_end_date = dateadd(day, 7 - datepart(dw, @startdate), @startdate)

    select @week_end_date week_end_date

    set @startdate = dateadd(week, 1, @startdate)   
end

[![enter image description here][1]][1]

I want to achieve the following result

week_start date             week_end_date
-----------------------------------------
2021-01-01                   2021-01-02
2021-01-03                   2021-01-09
2021-01-10                   2021-01-16
.
.
.
.
.
.
2021-12-26                  2021-12-31
.
.

I am trying to get start_date and end_date of the week for every week, but I want the start date of the first week to be 2020-01-01 and end date of last week 2020-12-31

In both the cases else is running

CodePudding user response:

I'm guessing that you really only need to cover a full calendar year. The first two CTEs are just creating a "numbers table". You could plug in a replacement if necessary. I'm also assuming a datefirst setting of 7.

with d as (
    select n from (values (0), (1), (2), (3), (4), (5), (6), (7)) t(n)
), w as (
    select d0.n   d1.n * 8 as offset from d as d0 cross join d as d1
), weeks as (
    select
        offset   1 as weeknum,
        dateadd(week, offset, basedate) as weekstart,
        dateadd(day, 6, dateadd(week, offset, basedate)) as weekend
    from w cross apply (
        select dateadd(day, 1 - datepart(weekday, @startdate), @startdate)
    ) as v(basedate)
)
select
    weeknum,
    case when weekstart < @startdate then @startdate else weekstart end,
    case when weekend   > @enddate   then @enddate   else weekend end
from weeks
where weekstart <= @enddate;

https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=5f900ecd26b92e4a112f191730958cae

CodePudding user response:

I suspect you want something like that, which will keep all the dates within the range specified. Hardcoding to a single year, which is almost over, is not good long term plan.

In Azure SQL, you can do this

declare @startdate date='2021-01-01'
declare @enddate date='2021-12-31'
declare @curdate date=@startdate
declare @week_end_date date

while(@curdate<=@enddate)
begin
    set @curdate= DATEADD(day,1-datepart(dw,@curdate),@curdate)
    select GREATEST(@startdate,@curdate) week_start_date

    set @week_end_date=dateadd(day,7-datepart(dw,@curdate),@curdate)
    select LEAST(@enddate,@week_end_date) week_end_date

    set @curdate= dateadd(week,1,@curdate)    
end

For SQL Server 2019, GREATEST/LEAST aren't available yet.

    declare @startdate date='2021-01-01'
    declare @enddate date='2021-12-31'
    declare @curdate date=@startdate
    declare @week_end_date date
    
    while(@curdate<=@enddate)
    begin
        set @curdate= DATEADD(day,1-datepart(dw,@curdate),@curdate)
        select IIF(@startdate>@curdate,@startdate,@curdate) week_start_date
    
        set @week_end_date=dateadd(day,7-datepart(dw,@curdate),@curdate)
        select IIF(@week_end_date > @enddate,@enddate, @week_end_date) week_end_date
    
        set @curdate= dateadd(week,1,@curdate)    
    end
  • Related