Hay un enlace aquí para otros intentos anteriores http://www.sqlteam. com/forums/topic.asp?TOPIC_ID=60510
Este es el código ANTIGUO de la función
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
Después de combinar la brillante respuesta de @AndriyM con la mía, nos queda 1 línea. Este es el NUEVO código.
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
Explicación del código antiguo (no voy a explicar el código nuevo. Son fragmentos de mi código y del código de AndriyM):
Encontrar el día de la semana 4 de la fecha elegida
dateadd(week, datediff(day, 0, @date)/7, 3)
Encontrar el isoaño:el año del día de la semana 4 de una semana siempre es el mismo año que el isoaño de esa semana
datediff(yy, 0, day4)
Al sumar 3 días al primer día del isoaño se encuentra un día aleatorio de la primera isosemana del isoaño
dateadd(yy, datediff(yy, 0, day4),3)
encontrar la semana relativa de la primera isosemana del isoaño
datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7
Encontrar el lunes menos 4 días de la primera isosemana da como resultado el jueves de la semana ANTES del primer día de la primera isosemana del isoaño
dateadd(ww, datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7,-4)
Sabiendo el primer jueves de la semana antes de la primera isoweek y el primer jueves de la semana elegida, hace que sea bastante fácil calcular la semana, no importa qué configuración tenga la fecha primero, ya que los días de la semana de ambas fechas son los jueves.
datediff(ww, dateadd(ww, datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7,-4),day4)