it-swarm.it

ottieni DATEDIFF escludendo i fine settimana usando il server sql

Sto usando questa domanda per ottenere il tempo necessario.

SELECT DATEDIFF(dd, ActualStartDate, ActualCompletionDate) AS TimeTaken
FROM TableName

Ora voglio escludere i fine settimana e includere solo lunedì-venerdì con giorni contati.

22
Sami

Query di esempio sotto, ecco alcuni dettagli su come ho risolto.

Usando DATEDIFF(WK, ...) ci darà il numero di settimane tra le 2 date. SQL Server valuta questo come differenza tra i numeri settimanali piuttosto che in base al numero di giorni. Questo è perfetto, dal momento che possiamo usare questo per determinare quanti weekend sono passati tra le date. 

Quindi possiamo moltiplicare questo valore per 2 per ottenere il numero di giorni del fine settimana che si sono verificati e sottrarlo dal DATEDIFF(dd, ...) per ottenere il numero di giorni della settimana. 

Questo non si comporta correttamente al 100% quando la data di inizio o di fine cade di domenica, però. Così ho aggiunto in alcuni casi la logica alla fine del calcolo per gestire quelle istanze.

Si potrebbe anche voler considerare se DATEDIFF dovrebbe essere completamente inclusivo. per esempio. La differenza tra 9/10 e 9/11 1 giorno o 2 giorni? In quest'ultimo caso, dovrai aggiungere 1 al prodotto finale.

declare @d1 datetime, @d2 datetime
select @d1 = '9/9/2011',  @d2 = '9/18/2011'

select datediff(dd, @d1, @d2) - (datediff(wk, @d1, @d2) * 2) -
       case when datepart(dw, @d1) = 1 then 1 else 0 end +
      case when datepart(dw, @d2) = 1 then 1 else 0 end
48
Derek Kromm

Ho trovato quando ho usato questo c'era un problema quando d1 cadeva il sabato. Di seguito è quello che ho usato per correggere questo.

declare @d1 datetime, @d2 datetime
select @d1 = '11/19/2011' ,  @d2 = '11/28/2011'

select datediff(dd, @d1, @d2) +case when datepart(dw, @d1) = 7 then 1 else 0 end - (datediff(wk, @d1, @d2) * 2) -
 case when datepart(dw, @d1) = 1 then 1 else 0 end +
 case when datepart(dw, @d2) = 1 then 1 else 0 end
5
JeffFischer30
BEGIN 
DECLARE @totaldays INT; 
DECLARE @weekenddays INT;

SET @totaldays = DATEDIFF(DAY, @startDate, @endDate) 
SET @weekenddays = ((DATEDIFF(WEEK, @startDate, @endDate) * 2) + -- get the number of weekend days in between
                       CASE WHEN DATEPART(WEEKDAY, @startDate) = 1 THEN 1 ELSE 0 END + -- if selection was Sunday, won't add to weekends
                       CASE WHEN DATEPART(WEEKDAY, @endDate) = 6 THEN 1 ELSE 0 END)  -- if selection was Saturday, won't add to weekends

Return (@totaldays - @weekenddays)

FINE 

Questo è su SQL Server 2014

1
JBelfort

Se odiate le dichiarazioni CASE tanto quanto me, e volete essere in grado di utilizzare la soluzione in linea nelle vostre domande, basta ottenere la differenza di giorni e sottrarre il conteggio dei giorni del fine settimana e avrete il risultato desiderato:

declare @d1 datetime, @d2 datetime,  @days int
select @d1 = '2018/10/01',  @d2 = '2018/11/01'

SET @days = DateDiff(dd, @d1, @d2) - DateDiff(ww, @d1, @d2)*2
print @days

(L'unica avvertenza - o almeno il punto da tenere a mente - è che questo calcolo non include l'ultima data, quindi potresti dover aggiungere un giorno alla data di fine per ottenere un risultato inclusivo)

1
Frank Bailey
declare @d1 datetime, @d2 datetime
select @d1 = '4/19/2017',  @d2 = '5/7/2017'

DECLARE @Counter int = datediff(DAY,@d1 ,@d2 )

DECLARE @C int = 0
DECLARE @SUM int = 0





 WHILE  @Counter > 0
  begin
 SET @SUM = @SUM + IIF(DATENAME(dw, 

 DATEADD(day,@c,@d1))IN('Sunday','Monday','Tuesday','Wednesday','Thursday')
 ,1,0)



SET @Counter = @Counter - 1
set @c = @c +1
end

select @Sum
0
Mohamad Malik

Utilizzando https://stackoverflow.com/a/1804095 e la risposta di JeffFisher30 sopra ( https://stackoverflow.com/a/14572370/6147425 ) e il mio bisogno di avere giorni frazionari, ho scritto Questo:

DateDiff(second,Start_Time,End_Time)/86400.0
            -2*DateDiff(week, Start_Time, End_Time)
            -Case When (DatePart(weekday, Start_Time)[email protected]@DateFirst)%7 = 1 Then 1 Else 0 End
            +Case When (DatePart(weekday, End_Time)[email protected]@DateFirst)%7 = 1 Then 1 Else 0 End
0
Jeff Winchell

Voglio solo condividere il codice che ho creato che potrebbe aiutarti.

DECLARE @MyCounter int = 0, @TempDate datetime, @EndDate datetime;
SET @TempDate = DATEADD(d,1,'2017-5-27')
SET @EndDate = '2017-6-3'

WHILE @TempDate <= @EndDate
    BEGIN
    IF DATENAME(DW,@TempDate) = 'Sunday' OR DATENAME(DW,@TempDate) = 'Saturday'
        SET @MyCounter = @MyCounter
    ELSE IF @TempDate not in ('2017-1-1', '2017-1-16', '2017-2-20', '2017-5-29', '2017-7-4', '2017-9-4', '2017-10-9', '2017-11-11', '2017-12-25')
        SET @MyCounter = @MyCounter + 1

    SET @TempDate = DATEADD(d,1,@TempDate)
    CONTINUE

END
PRINT @MyCounter
PRINT @TempDate

Se si dispone di una tabella festività, è possibile utilizzarla anche in modo da non dover elencare tutte le festività nella sezione ELSE SE del codice. Puoi anche creare una funzione per questo codice e usare la funzione ogni volta che ne hai bisogno nella tua query.

Spero che questo potrebbe aiutare anche.

0
Digitech Fender