Obtener el número de semana de una fecha en MS SQL Server 2005?

¿Es posible crear una instrucción sql que seleccione el número de la semana (NO el día de la semana o el día en una semana). Estoy creando una vista para seleccionar esta información adicional junto con un par de otros campos y, por lo tanto, no puedo usar un procedimiento almacenado. Soy consciente de que es posible crear un UDF para hacer el truco, pero si es posible, prefiero solo agregar una vista a esta base de datos, que tanto una vista como una función.

¿Algunas ideas? También de donde vengo, la semana comienza el lunes y la semana 1 es la primera semana del año con al menos 4 días.

Relacionado:

¿Cómo calculo el número de semana dada una fecha?

Tenga en cuenta que hay diferencias en lo que se considera el número correcto de la semana, según la cultura. Los números de la semana dependen de un par de suposiciones que difieren de un país a otro, vea el artículo de Wikipedia sobre el asunto . Existe un estándar ISO (ISO 8601) que se aplica a los números de semana.

La función DATEPART() integrada del servidor SQL no necesariamente hace Lo correcto. SQL Server asume que el día 1 de la semana 1 sería el 1 de enero, para muchas aplicaciones que están mal.

El cálculo correcto de los números semanales no es trivial, y se pueden encontrar diferentes implementaciones en la web. Por ejemplo, hay una UDF que calcula los números de semana ISO de 1930-2030 , siendo uno entre muchos otros. Deberá verificar qué funciona para usted.

Este es de Books Online (aunque es probable que desee usar el de la respuesta de Jonas Lincoln , la versión de BOL parece ser incorrecta):

 CREATE FUNCTION ISOweek (@DATE DATETIME) RETURNS INT AS BEGIN DECLARE @ISOweek INT SET @ISOweek = DATEPART(wk,@DATE) +1 -DATEPART(wk,CAST(DATEPART(yy,@DATE) AS CHAR(4))+'0104') -- Special cases: Jan 1-3 may belong to the previous year IF (@ISOweek=0) SET @ISOweek = dbo.ISOweek(CAST(DATEPART(yy,@DATE) - 1 AS CHAR(4))+'12'+ CAST(24+DATEPART(DAY,@DATE) AS CHAR(2)))+1 -- Special case: Dec 29-31 may belong to the next year IF ((DATEPART(mm,@DATE)=12) AND ((DATEPART(dd,@DATE)-DATEPART(dw,@DATE))>= 28)) SET @ISOweek=1 RETURN(@ISOweek) END GO 

Necesitas la semana ISO. Desde http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=60510 , aquí hay una implementación:

 drop function dbo.F_ISO_WEEK_OF_YEAR go create function dbo.F_ISO_WEEK_OF_YEAR ( @Date datetime ) returns int as /* Function F_ISO_WEEK_OF_YEAR returns the ISO 8601 week of the year for the date passed. */ begin declare @WeekOfYear int select -- Compute week of year as (days since start of year/7)+1 -- Division by 7 gives whole weeks since start of year. -- Adding 1 starts week number at 1, instead of zero. @WeekOfYear = (datediff(dd, -- Case finds start of year case when NextYrStart <= @date then NextYrStart when CurrYrStart <= @date then CurrYrStart else PriorYrStart end,@date)/7)+1 from ( select -- First day of first week of prior year PriorYrStart = dateadd(dd,(datediff(dd,-53690,dateadd(yy,-1,aa.Jan4))/7)*7,-53690), -- First day of first week of current year CurrYrStart = dateadd(dd,(datediff(dd,-53690,aa.Jan4)/7)*7,-53690), -- First day of first week of next year NextYrStart = dateadd(dd,(datediff(dd,-53690,dateadd(yy,1,aa.Jan4))/7)*7,-53690) from ( select --Find Jan 4 for the year of the input date Jan4 = dateadd(dd,3,dateadd(yy,datediff(yy,0,@date),0)) ) aa ) a return @WeekOfYear end go 

Parece que la función DATEPART mssql debería ayudarte con …

 DATEPART(wk, 'Jan 1, xxxx') = 1 

Bueno, lo seré … Resulta que hay una manera de establecer el primer día de la semana, DATEFIRST

 SET DATEFIRST 1 -- for monday 

Actualización : ahora entiendo mejor lo que quiere el OP … que es la lógica personalizada para esto. No creo que MSSQL tenga funciones con un nivel de personalización tan rico. Pero puedo estar equivocado … Creo que deberás rodar tu propia FDU aquí … lo siento

OLVIDAR LAS OTRAS RESPUESTAS

La pregunta especifica ” la semana comienza el lunes y la semana 1 es la primera semana del año con al menos 4 días. Esto es el estándar ISO 8601 y lo que proporciona esta respuesta. Esta función se usa en producción en nuestro sitio.

Esto es todo lo que necesita:

 CREATE FUNCTION ISOweek (@DATE DATETIME) RETURNS INT AS BEGIN RETURN (datepart(DY, datediff(d, 0, @DATE) / 7 * 7 + 3)+6) / 7 END GO 

Esto le devolverá el número de la semana de la fecha ingresada entre comillas

 SELECT DATEPART( wk, 'enter the date over here' ) 

Parece que datepart te llevará una parte del camino hasta allí, pero tendrás que adaptarte para obtener el número de semana correcto, según el día de la semana del 1 de enero del año correspondiente. No estoy lo suficientemente familiarizado con T-SQL para hacer eso, pero debería ser posible. Lástima que no hay un argumento de modo como en MySQL

¿Has considerado usar la función SEMANA?

Esto le permitirá obtener la semana del año correspondiente a la fecha especificada en que ingresa.

 SELECT { fn WEEK(GETDATE()) } AS WeekNumber, { fn WEEK(CONVERT(DATETIME, '2008-01-01 00:00:00', 102)) } AS FirstWeekOfYear, { fn WEEK(CONVERT(DATETIME, '2008-12-31 00:00:00', 102)) } AS LastWeekOfYear 

Esto genera los siguientes SQL2000 y SQL2005:

  • WeekNumber: 50
  • FirstWeekOfYear: 1
  • LastWeekOfYear: 53

Espero que esto ayude 🙂

¿Por qué una vez más, la gente hace montañas de lomas, me sorprende?

Tan sencillo…

 select DATEPART(wk, GETDATE())