2017-02-15 1 views
0

Donc, je dois ajouter quelques jours à une date, disons 30, mais les 30 jours ne peuvent pas être des jours de calendrier, ce sont des paramètres qui dépendent d'une logique derrière, donc, je dois trouver un moyen d'ajouter à une date 30 jours entre lundi et mercredi par exemple: Si j'ajoute 30 jours (du lundi au mercredi) au 15 février, je devrais avoir le 26 avril Si j'ajoute 30 jours (du dimanche au vendredi) à février 15e, je devrais obtenir le 17 marsSQL Server DATEADD jours de la semaine spécifiques

Si la situation n'est pas assez clair, faites le moi savoir et je vais essayer de donner une meilleure explication.

Merci.

+0

voulez-vous dire jours ouvrables? – McNets

+0

@McNets bien, mais pas seulement les jours de travail, ça peut être du dimanche au vendredi, du lundi au mardi ... ça varie beaucoup, mais s'il y a un moyen de définir les jours de travail dans chaque requête, je peux travailler avec ce – rhernandez

+0

avez-vous une table de calendrier de recherche? – McNets

Répondre

1

D'abord, j'ai produit une série de dates entre StartDate et EndDate, mais il retourne jour de la semaine:

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) 

vous pouvez utiliser un simple WHERE IN() pour sélectionner le jour de la semaine que vous souhaitez inclure et compter les jours retournés.

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); 

Prenez soin de jour sapins de la semaine dans votre SQL Server, vous pouvez le modifier avec SET DATEFIRST.

Vérifiez ici: http://rextester.com/WCLIXM28868

+0

Ça a l'air génial! va l'essayer et vous le faire savoir! – rhernandez

+0

Génial! c'est exactement ce que je cherchais, est rapide et facile à comprendre. Je vous remercie! – rhernandez

+0

Je suis heureux de pouvoir vous aider. – McNets

1

je le ferais avec un CTE récursive, comme ceci:

-- 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 

La requête ci-dessus est pour Mon-MER. Pour le rendre Sun-vendredi modifier les drapeaux actifs dans les jours CTE

+0

Cela pourrait fonctionner, Puisque je reçois le nombre de jour (0 = dimanche, 7 = samedi), je pourrais utiliser un cas où ... au CTE, je vais essayer cette approche. Je vous remercie! – rhernandez

+0

Cela fonctionne bien, mais il pourrait être lent dans la production – rhernandez