SQL server DATEADD specific week days

三世轮回 提交于 2019-12-25 16:38:04

问题


So I need to add some days to a date, let's say 30, but the 30 days can't be calendar days, they are parameters that depend on some logic behind, so, I need to find a way to add to a date 30 days between mondays and wednesday for example: If I add 30 (mon to wed) days to february 15th, I should get April 26 If I add 30 (sun to fri) days to february 15th, I should get March 17

If the situation is not clear enough just let me know ant I'll try to give a better explanation.

Thanks.


回答1:


First I've generated a series of dates between StartDate and EndDate, but it returns Day of Week:

SELECT  DATEPART(weekday, DATEADD(DAY, nbr - 1, @StartDate)) as dow
FROM    (SELECT    ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
         FROM      sys.columns c
         )nbrs
WHERE   nbr - 1 <= DATEDIFF(DAY, @StartDate, @EndDate)

Then you can use a simple WHERE IN () to select wich day of week you want to include, and count the returned days.

DECLARE @StartDate DATE = '20170101'
        , @EndDate DATE = '20170131'

SELECT COUNT(*) AS DAYS
FROM (
        SELECT  DATEPART(weekday, DATEADD(DAY, nbr - 1, @StartDate)) as dow
        FROM    (SELECT    ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
                 FROM      sys.columns c
                )nbrs
        WHERE   nbr - 1 <= DATEDIFF(DAY, @StartDate, @EndDate)
    ) T1
WHERE DOW IN (3,4,5);

Take care of firs day of week in your SQL Server, you can change it with SET DATEFIRST.

Check it here: http://rextester.com/WCLIXM28868




回答2:


I would do it with a recursive CTE, like this:

-- set datefirst as Sunday. You may need to adjust it ot the correct Datefirst value for your locale
SET DATEFIRST 7

declare @d datetime
set @d = '2017-02-15'
SELECT @d

;with 
days as( 
-- this CTE where you define the active days. The days start 
select 1 as d, 0 as active -- sunday
union
select 2 as d, 1 as active -- monday
union 
select 3 as d, 1 as active
union 
select 4 as d, 1 as active
union 
select 5 as d, 0 as active
union 
select 6 as d, 0 as active 
union
select 7 as d, 0 as active -- saturday

),
n as (
select CASE WHEN DATEPART(dw, DATEADD(d, 1, @d)) IN (select d from days where active=1) THEN 1 ELSE 0 END as n, @d as dt
union all 
select CASE WHEN DATEPART(dw, DATEADD(d, 1, dt)) IN (select d from days where active=1) THEN n+1 else n end, DATEADD(d, 1, dt)
from n where n < 30)
--SELECT * from n order by n
SELECT top 1 @d = dt from n order by n desc

select @d

The above query is for Mon-Wed. To make it Sun-Friday modify the active flags in the days CTE



来源:https://stackoverflow.com/questions/42261774/sql-server-dateadd-specific-week-days

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!