Usuário com melhor resposta
dias não úteis antes de uma data

Pergunta
-
acho que a melhor forma para mostrar meu problema é dando de cara logo um exemplo:
tenho a data 01/04/2013. eu preciso verificar quantos dias não úteis tem antes dessa data. nesse caso eu tenho 3. que são 31/03/2013, 30/03/2013 e 29/03/2013.
ou seja, a data que for informada (como parametro, por exemplo), preciso verificar quantos dias não úteis tem antes dela.
como posso fazer?
Respostas
-
Rafa,
Usei como base um thread aqui do fórum mesmo.
http://social.msdn.microsoft.com/Forums/pt-BR/transactsqlpt/thread/95ed57e5-c9df-4dda-933f-16077b8534f5
Veja este exemplo:
DECLARE @DATA DATETIME = '2013-04-01' DECLARE @RANGE INT = -7 DECLARE @RESULTADO TABLE ( DIANAOUTIL DATETIME ) DECLARE @DATAINICIO DATETIME = DATEADD(DAY,@RANGE,@DATA) WHILE @DATAINICIO <= @DATA BEGIN IF DATEPART(WEEKDAY, @DATAINICIO) IN (7,1) OR @DATAINICIO IN ( SELECT FERIADO FROM FERIADOS ) -- PARA OS FERIADOS TEM QUE TER UMA TABELA INSERT INTO @RESULTADO SELECT @DATAINICIO SELECT @DATAINICIO = DATEADD(DAY,1,@DATAINICIO) END SELECT * FROM @RESULTADO
SQL Fiddle para ver em funcionamento:
http://sqlfiddle.com/#!3/daddd/6Vitor Mendes | Seu feedback é muito importante para todos!
Visite o meu site: http://www.vitormendes.com.br/- Marcado como Resposta rafa-martin segunda-feira, 1 de abril de 2013 18:02
-
Rafa, fiz uma pequena alteração colocando mais um else no segundo case que vai funcionar, então no primeiro case, ele faz uma validação somente do dia da semana, se for domingo então ha 1 dia não util, segunda ha 2, terça nenhum e assim por diante, ja no segundo case ja é guardado o valor da variavel da quantidade de dias não uteis da semana que são fixos (sabado e domingo) e no segundo ele só valida na sua tabela de feriados 2 dias antes se ha algum registro, se tiver ele somente incrementa 1 ou 2 dias dependendo da sua tabela de feriados, veja se funciona agora:
Declare @data datetime Declare @aux int set @data = '2013-03-25' set @aux = 0 set @aux = ( case when DATEPART(WEEKDAY, @data) = 1 then 1 -- Domingo when DATEPART(WEEKDAY, @data) = 2 then 2 -- Segunda when DATEPART(WEEKDAY, @data) = 3 then 0 -- terca when DATEPART(WEEKDAY, @data) = 4 then 0 -- quarta when DATEPART(WEEKDAY, @data) = 5 then 0 -- quinta when DATEPART(WEEKDAY, @data) = 6 then 0 -- sexta when DATEPART(WEEKDAY, @data) = 7 then 0 -- Sabado end) select @aux set @aux = ( case when @aux = 0 and @data - 1 in (select feriado from #temp) then @aux + 1 when @aux = 0 and @data - 1 in (select feriado from #temp) and @data - 2 in (select feriado from #temp) then @aux + 2 when @aux = 1 and @data - 2 in (select feriado from #temp) then @aux + 1 when @aux = 1 and @data - 2 in (select feriado from #temp) and @data - 3 in (select feriado from #temp) then @aux + 2 when @aux = 2 and @data - 3 in (select feriado from #temp) then @aux + 1 when @aux = 2 and @data - 3 in (select feriado from #temp) and @data - 4 in (select feriado from #temp) then @aux + 2 Else @aux end) select @aux
Alexandre Matayosi Conde Mauricio.
- Marcado como Resposta rafa-martin segunda-feira, 1 de abril de 2013 18:02
Todas as Respostas
-
Rafa, primeiramente o que seriam dias não uteis ? sabado e domingo por exemplo seria facil de se fazer utilizando o datepart e pegando os dias anteriores validando se é sabado ou domingo, agora para feriados o sql não tem uma tabela de feriados, para isto acredito que voce tenha que ter uma tabela de cadastro destes dias para fazer esta validação.
Alexandre Matayosi Conde Mauricio.
-
-
Bom, pode não ser a maneira mais perfomatica que exista mas esta funcionando, nesse exemplo sua tabela de feriados seria a #temp e a data que voce quer verificar esta na @data o resultado vai sair na @aux, veja o exemplo que montei:
create table #temp (Feriado datetime) insert into #temp values ('2013-03-29') Declare @data datetime Declare @aux int set @data = '2013-04-01' set @aux = 0 set @aux = ( case when DATEPART(WEEKDAY, @data) = 1 then 1 -- Domingo when DATEPART(WEEKDAY, @data) = 2 then 2 -- Segunda when DATEPART(WEEKDAY, @data) = 3 then 0 -- terca when DATEPART(WEEKDAY, @data) = 4 then 0 -- quarta when DATEPART(WEEKDAY, @data) = 5 then 0 -- quinta when DATEPART(WEEKDAY, @data) = 6 then 0 -- sexta when DATEPART(WEEKDAY, @data) = 7 then 0 -- Sabado end) set @aux = ( case when @aux = 0 and @data - 1 in (select feriado from #temp) then @aux + 1 when @aux = 0 and @data - 1 in (select feriado from #temp) and @data - 2 in (select feriado from #temp) then @aux + 2 when @aux = 1 and @data - 2 in (select feriado from #temp) then @aux + 1 when @aux = 1 and @data - 2 in (select feriado from #temp) and @data - 3 in (select feriado from #temp) then @aux + 2 when @aux = 2 and @data - 3 in (select feriado from #temp) then @aux + 1 when @aux = 2 and @data - 3 in (select feriado from #temp) and @data - 4 in (select feriado from #temp) then @aux + 2 end) select @aux
Alexandre Matayosi Conde Mauricio.
-
Rafa,
Usei como base um thread aqui do fórum mesmo.
http://social.msdn.microsoft.com/Forums/pt-BR/transactsqlpt/thread/95ed57e5-c9df-4dda-933f-16077b8534f5
Veja este exemplo:
DECLARE @DATA DATETIME = '2013-04-01' DECLARE @RANGE INT = -7 DECLARE @RESULTADO TABLE ( DIANAOUTIL DATETIME ) DECLARE @DATAINICIO DATETIME = DATEADD(DAY,@RANGE,@DATA) WHILE @DATAINICIO <= @DATA BEGIN IF DATEPART(WEEKDAY, @DATAINICIO) IN (7,1) OR @DATAINICIO IN ( SELECT FERIADO FROM FERIADOS ) -- PARA OS FERIADOS TEM QUE TER UMA TABELA INSERT INTO @RESULTADO SELECT @DATAINICIO SELECT @DATAINICIO = DATEADD(DAY,1,@DATAINICIO) END SELECT * FROM @RESULTADO
SQL Fiddle para ver em funcionamento:
http://sqlfiddle.com/#!3/daddd/6Vitor Mendes | Seu feedback é muito importante para todos!
Visite o meu site: http://www.vitormendes.com.br/- Marcado como Resposta rafa-martin segunda-feira, 1 de abril de 2013 18:02
-
alexandre,
tem um detalhe: por exemplo dia 25/03/2013 é uma segunda - feira. então tenho 2 dias não úteis, seria domingo (24/03) e sábado (23/03). só que no segundo case está me trazendo o @aux null. no primeiro está correto. pq? não consegui entender porque no segundo case tem @data -2, -3, -1, etc...
- Editado rafa-martin segunda-feira, 1 de abril de 2013 17:55 r
-
Rafa, fiz uma pequena alteração colocando mais um else no segundo case que vai funcionar, então no primeiro case, ele faz uma validação somente do dia da semana, se for domingo então ha 1 dia não util, segunda ha 2, terça nenhum e assim por diante, ja no segundo case ja é guardado o valor da variavel da quantidade de dias não uteis da semana que são fixos (sabado e domingo) e no segundo ele só valida na sua tabela de feriados 2 dias antes se ha algum registro, se tiver ele somente incrementa 1 ou 2 dias dependendo da sua tabela de feriados, veja se funciona agora:
Declare @data datetime Declare @aux int set @data = '2013-03-25' set @aux = 0 set @aux = ( case when DATEPART(WEEKDAY, @data) = 1 then 1 -- Domingo when DATEPART(WEEKDAY, @data) = 2 then 2 -- Segunda when DATEPART(WEEKDAY, @data) = 3 then 0 -- terca when DATEPART(WEEKDAY, @data) = 4 then 0 -- quarta when DATEPART(WEEKDAY, @data) = 5 then 0 -- quinta when DATEPART(WEEKDAY, @data) = 6 then 0 -- sexta when DATEPART(WEEKDAY, @data) = 7 then 0 -- Sabado end) select @aux set @aux = ( case when @aux = 0 and @data - 1 in (select feriado from #temp) then @aux + 1 when @aux = 0 and @data - 1 in (select feriado from #temp) and @data - 2 in (select feriado from #temp) then @aux + 2 when @aux = 1 and @data - 2 in (select feriado from #temp) then @aux + 1 when @aux = 1 and @data - 2 in (select feriado from #temp) and @data - 3 in (select feriado from #temp) then @aux + 2 when @aux = 2 and @data - 3 in (select feriado from #temp) then @aux + 1 when @aux = 2 and @data - 3 in (select feriado from #temp) and @data - 4 in (select feriado from #temp) then @aux + 2 Else @aux end) select @aux
Alexandre Matayosi Conde Mauricio.
- Marcado como Resposta rafa-martin segunda-feira, 1 de abril de 2013 18:02
-