Obtendo número de semana fora de uma data no MS SQL Server 2005?

É possível criar uma instrução sql que selecione o número da semana (NÃO o dia da semana – ou o número do dia em uma semana). Eu estou criando uma visão para selecionar essa informação extra junto com um par de outros campos e, portanto, não pode usar um procedimento armazenado. Estou ciente de que é possível criar uma UDF para fazer o truque, mas, se possível, prefiro apenas adicionar uma visualização a esse database, do que uma visualização e uma function.

Alguma ideia? Também de onde eu venho, a semana começa segunda-feira e a semana 1 é a primeira semana do ano com pelo menos 4 dias.

Relacionado:

Como faço para calcular o número da semana com uma data?

Esteja ciente de que existem diferenças no que é considerado o número correto da semana, dependendo da cultura. Os números das semanas dependem de algumas suposições que diferem de país para país, veja o artigo da Wikipedia sobre o assunto . Existe uma norma ISO (ISO 8601) que se aplica aos números das semanas.

A function DATEPART() integrada do servidor SQL não faz necessariamente a coisa certa. O SQL Server assume que o dia 1 da semana 1 seria 1 de janeiro, pois muitos aplicativos estão errados.

Calcular números de semanas corretamente não é trivial e diferentes implementações podem ser encontradas na web. Por exemplo, há um UDF que calcula os números da semana ISO de 1930 a 2030 , sendo um entre muitos outros. Você terá que verificar o que funciona para você.

Este é do Books Online (embora você provavelmente queira usar o da resposta de Jonas Lincoln , a versão do BOL parece estar incorreta):

 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 

Você precisa da semana ISO. De http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=60510 , aqui está uma implementação:

 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 a function mssql DATEPART deve ajudá-lo com …

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

Bem, eu vou ser .. Acontece que há uma maneira de definir o primeiro dia da semana, DATEFIRST

 SET DATEFIRST 1 -- for monday 

Update : Agora eu entendo melhor, o que o OP quer .. que é lógica personalizada para isso. Eu não acho que o MSSQL teria funções com um nível tão alto de personalização. Mas eu posso estar errado … Eu acho que você terá que rolar sua própria UDF aqui … desculpe

ESQUECER AS OUTRAS RESPOSTAS

A pergunta especifica ” a semana começa segunda-feira e a semana 1 é a primeira semana do ano com pelo menos 4 dias. Esta é a norma ISO 8601 e o que esta resposta fornece. Esta function é usada na produção em nosso site.

Isso é tudo que você precisa:

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

Isso retornará o número da semana da data inserida entre aspas

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

Parece que a data vai levar você até lá, mas você terá que se ajustar para obter o número correto da semana, com base no dia da semana de 1º de janeiro do ano em questão. Eu não estou familiarizado o suficiente com o T-SQL para fazer isso, mas deveria ser possível. Pena que não existe um argumento mode como no MySQL

você já pensou em usar a function WEEK?

Isso fará com que você a semana do ano para a data especificada que você passar.

 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 

Isso gera o seguinte SQL2000 e SQL2005:

  • Número da semana: 50
  • FirstWeekOfYear: 1
  • LastWeekOfYear: 53

Eu espero que isso ajude 🙂

Por que mais uma vez, as pessoas fazem montanhas de montes de montanhas, isso me surpreende?

Tão simples…

 select DATEPART(wk, GETDATE())