Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Isoweek in SQL Server 2005

C'è un collegamento qui per altri tentativi precedenti http://www.sqlteam. com/forums/topic.asp?TOPIC_ID=60510

Questo è il VECCHIO codice per la funzione

CREATE function f_isoweek(@date datetime)
RETURNS INT
as
BEGIN
DECLARE @rv int

SELECT @rv = datediff(ww, dateadd(ww, datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7,-4),day4)
FROM (SELECT dateadd(ww, datediff(day, 0, @date)/7, 3) day4) a

RETURN @rv
END

Dopo aver combinato la brillante risposta di @AndriyM con la mia, siamo scesi a 1 riga. Questo è il NUOVO codice.

CREATE function f_isoweek(@date datetime)
RETURNS INT
as
BEGIN

RETURN (datepart(DY, datediff(d, 0, @date) / 7 * 7 + 3)+6) / 7
-- replaced code for yet another improvement.
--RETURN (datepart(DY, dateadd(ww, datediff(d, 0, @date) / 7, 3))+6) / 7

END

Spiegazione per il vecchio codice (non spiegherò il nuovo codice. Sono frammenti del mio codice e del codice di AndriyM):

Trovare il giorno della settimana 4 della data scelta

dateadd(week, datediff(day, 0, @date)/7, 3) 

Trovare isoanno - l'anno del giorno 4 della settimana è sempre lo stesso anno dell'isoanno di quella settimana

datediff(yy, 0, day4)

Quando si aggiungono 3 giorni al primo giorno dell'isoanno viene trovato un giorno casuale della prima isosettimana dell'isoanno

dateadd(yy, datediff(yy, 0, day4),3)

trovare la settimana relativa della prima isosettimana dell'isoanno

datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7

Trovando il lunedì meno 4 giorni della prima isosettimana si ottiene il giovedì della settimana PRIMA del primo giorno della prima isosettimana dell'isoanno

dateadd(ww, datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7,-4)

Conoscendo il primo giovedì della settimana prima della prima isoweek e il primo giovedì della settimana scelta, è abbastanza facile calcolare la settimana, non importa quale impostazione abbia datefirst poiché i giorni feriali di entrambe le date sono giovedì.

datediff(ww, dateadd(ww, datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7,-4),day4)