Preciso determinar as datas que são a "3ª sexta-feira de cada mês" para um intervalo de datas de "1.1.1996 - 30.8.2014" no SQL Server.
Espero que eu deva usar uma combinação de DENSE_RANK()
e PARTITION BY()
para definir "rank = 3". No entanto, sou novo no SQL e não consigo encontrar o código correto.
Dado:
A 3ª sexta-feira do mês sempre cairá de 15 a 21 do mês
Você também pode usar
weekday
comdatepart()
, mas é mais legível com um nome IMO. As comparações de strings obviamente serão mais lentas.Para obter uma resposta independente de idioma/cultura, você precisa levar em consideração diferentes nomes de dias da semana e início da semana.
Na Itália, sexta-feira é "Venerdì" e o primeiro dia da semana é segunda-feira, não domingo como nos Estados Unidos.
1900-01-01
era uma segunda-feira, então podemos usar essas informações para calcular o dia da semana de maneira independente do local:Outra maneira, que usa a resposta de Phil como base e cuida de configurações diferentes:
O
5
código (se você quiser um dia da semana diferente de sexta-feira) deve ser (o mesmo que osSET DATEFIRST
códigos):Você também pode usar apenas uma data "conhecidamente válida" para estar seguro em relação às configurações de idioma. Por exemplo, se estiver procurando por sextas-feiras, verifique um calendário e veja que 2 de janeiro de 2015 foi uma sexta-feira. A primeira comparação poderia então ser escrita como:
Veja também Como obter o enésimo dia da semana de um mês , de Peter Larsson.
Na verdade, escrevi um artigo sobre esse tipo de cálculo aqui
Basicamente, você pode usar o seguinte código para encontrar a 3ª sexta-feira de cada mês em qualquer intervalo de datas
Sim, eu sei que este post é antigo. Pensei em fornecer uma visão diferente sobre as coisas, apesar de sua idade. Hehe... e minhas desculpas. Acabei de perceber que quase dupliquei o que @jyao postou acima.
Com base na edição atual da pergunta original do OP, não consegui descobrir por que as pessoas estavam postando as respostas que fizeram.
Olhando através das edições, encontrei a pergunta original e postei abaixo ...
A parte da pergunta original que enfatizei em negrito parece ser a chave. Eu certamente poderia estar incorreto, mas parece-me que o OP estava afirmando que ele tem uma tabela "Calendar" chamada "dbo.datestable" e, para mim, isso faz uma grande diferença e agora entendo porque muitas das respostas são o que estão incluindo aquele que gerou as datas porque foi postado em 10 de novembro... um dia após a edição final da pergunta, que removeu os vestígios finais da referência ao "dbo.datestable".
Como eu disse, posso estar errado, mas aqui está minha interpretação da pergunta original.
Como os métodos convencionais para fazer isso já foram abordados, adicionarei uma alternativa que pode ser útil para alguns.
Vamos simular algumas das colunas que acho que o OP já terá em sua tabela. Claro, estou supondo os nomes das colunas. Subscreva quaisquer colunas equivalentes para sua tabela "Calendário". Além disso, estou fazendo tudo isso no TempDB para não correr o risco de interferir na tabela "Calendário" real de alguém.
Também é certo que não sei se o OP pode fazer alterações em sua tabela "Calendário", então isso pode não ajudá-lo, mas pode ajudar outras pessoas. Com isso em mente, vamos adicionar uma coluna DWoM (Day of Week for the Month). Se você não gostar do nome, sinta-se à vontade para alterá-lo para o que quiser em sua própria caixa.
Em seguida, precisamos preencher a nova coluna. O OP teve uma noção disso em sua postagem original não adulterada.
Agora, como essa é uma coluna de comprimento fixo, isso acabou de criar várias divisões de página, então precisamos reconstruir o Clustered Index para "reempacotar" a tabela para ter o máximo de linhas por página possível por causa do desempenho.
Uma vez feito isso, as consultas que fazem coisas como retornar na 3ª sexta-feira de cada mês em um determinado intervalo de datas tornam-se triviais e bastante óbvias de ler.
Aqui está uma solução simples de recortar e colar. Você pode transformar isso em uma função, se quiser.