Usuário com melhor resposta
Dias entre alta e baixa temporada

Pergunta
-
Pessoal,
Eu tenho a seguinte tabela:
ID PeriodoInicial PeriodoFinal Temporada
1 2012-07-01 00:00:00.000 2012-07-31 00:00:00.000 Alta 2 2012-12-15 00:00:00.000 2012-12-31 00:00:00.000 Alta 3 2013-01-01 00:00:00.000 2013-01-31 00:00:00.000 Alta 4 2013-02-09 00:00:00.000 2013-02-12 00:00:00.000 Feriado O que eu preciso fazer é dado um periodo saber a qtade de dias que estão em algumas das temporadas acima.
Por exemplo se o periodo for 01-09-2012 a 15-09-2012 ele retorna 0
Se for 01-12-2012 a 16-12-2012 ele retorna 2
Se for 01-02-2013 a 15-02-2013 ele retorna 4
Nunca implementei este tipo de consulta e to tendo uma certa dificuldade, cheguei a montar esta:SELECT Descricao, DATEDIFF(d, '20130201', EffectiveEndDate) AS NumberOfDays FROM (SELECT Descricao, CASE WHEN PeriodoFinal < '20130215' THEN PeriodoFinal ELSE '20130215' END AS EffectiveEndDate FROM CONFTemporada WHERE ([PeriodoFinal] >= '20130201' AND [PeriodoFinal] <= '20130215' AND [PeriodoInicial] <= '20130215' ) OR ([PeriodoInicial] <= '20130215' AND [PeriodoInicial] >= '20130201' AND [PeriodoFinal] >= '20130215' ) OR ([PeriodoInicial] >= '20130201' AND [PeriodoInicial] <= '20130215' AND [PeriodoFinal] <= '20130215' AND [PeriodoFinal] >= '20130201' ) ) AS SubSelect
Mas ele só retorna o total e não os dias dentro dos periodos..
http://BrunoZP.com.br || http://BrunoZP.com
Respostas
-
Isso não é tão simples fazer pois existem 5 variações possíveis:
- O período passado como parâmetro se encontra totalmente dentro de um período cadastrado na tabela;
- A data inicial passada como parâmetro se encontra dentro de um período cadastrado na tabela, mas a data final se encontra fora de um período cadastrado na tabela;
- A data final passada como parâmetro se encontra dentro de um período cadastrado na tabela, mas a data inicial se encontra fora de um período cadastrado na tabela;
- Tanto a data inicial quanto a data final passadas como parâmetro se encontram fora de qualquer período cadastrado na tabela, porém, existe um período cadastrado na tabela que compreende o período passado como parâmetro;
- Tanto a data inicial quanto a data final passadas como parâmetro se encontram fora de qualquer período cadastrado na tabela, e não existe nenhum período cadastrado na tabela que compreenda o período passado como parâmetro.
Segue exemplo de como contemplar todas estas possibilidades:
Declare @Tabela Table (ID int Identity, PeriodoInicial Date, PeriodoFinal Date, Temporada VarChar(20)) Insert Into @Tabela Values ('2012-07-01', '2012-07-31', 'Alta'), ('2012-12-15', '2012-12-31', 'Alta'), ('2013-01-01', '2013-01-31', 'Alta'), ('2013-02-09', '2013-02-12', 'Feriado') Declare @DataInicial Date, @DataFinal Date Set @DataInicial = '2012-12-20' Set @DataFinal = '2013-02-20' ;With CTE as ( Select Temporada, Dias = Case When (@DataInicial between PeriodoInicial and PeriodoFinal) and (@DataFinal between PeriodoInicial and PeriodoFinal) then DateDiff(dd, @DataInicial, @DataFinal) When (@DataInicial between PeriodoInicial and PeriodoFinal) and (@DataFinal > PeriodoFinal) then DateDiff(dd, @DataInicial, PeriodoFinal) When (@DataInicial < PeriodoInicial) and (@DataFinal between PeriodoInicial and PeriodoFinal) then DateDiff(dd, PeriodoInicial, @DataFinal) Else DateDiff(dd, PeriodoInicial, PeriodoFinal) End From @Tabela Where ((@DataInicial between PeriodoInicial and PeriodoFinal) and (@DataFinal between PeriodoInicial and PeriodoFinal)) or ((@DataInicial between PeriodoInicial and PeriodoFinal) and (@DataFinal > PeriodoFinal)) or ((@DataInicial < PeriodoInicial) and (@DataFinal between PeriodoInicial and PeriodoFinal)) or ((PeriodoInicial between @DataInicial and @DataFinal) and (PeriodoFinal between @DataInicial and @DataFinal)) ) Select Temporada, TotalDias = Sum(Dias) From CTE Group by Temporada
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.- Sugerido como Resposta Roberson Ferreira _ quarta-feira, 19 de setembro de 2012 17:26
- Marcado como Resposta BrunoZP quarta-feira, 19 de setembro de 2012 18:04
Todas as Respostas
-
Bruno veja se esse exemplo te ajuda.
--declarando uma tabela temporária declare @t as table (ID int, PeriodoInicial date, PeriodoFinal date, Temporada varchar(15) ) --populando a tabela insert into @t values (1,'2012-07-01 00:00:00.000','2012-07-31 00:00:00.000','Alta'), (2,'2012-12-15 00:00:00.000','2012-12-31 00:00:00.000','Alta'), (3,'2013-01-01 00:00:00.000','2013-01-31 00:00:00.000','Alta'), (4,'2013-02-09 00:00:00.000','2013-02-12 00:00:00.000','Feriado') /* Por exemplo se o periodo for 01-09-2012 a 15-09-2012 ele retorna 0 Se for 01-12-2012 a 16-12-2012 ele retorna 2 Se for 01-02-2013 a 15-02-2013 ele retorna 4 */ declare @dtIni as date , @dtFim as date --Setando valores aos paramentros select @dtIni = '2012-12-01', @dtFim = '2012-12-16' --Resultado da 1º opção select * from @t where PeriodoInicial between @dtIni and @dtFim or PeriodoFinal between @dtIni and @dtFim -- mudando o valor dos parâmentros select @dtIni = '2013-02-01', @dtFim = '2013-02-15' --Resultado da 2º opção select * from @t where PeriodoInicial between @dtIni and @dtFim or PeriodoFinal between @dtIni and @dtFim
Se a minha ajuda lhe for útil não esqueça de classificar. Att. Leonardo Marcelino
-
Isso não é tão simples fazer pois existem 5 variações possíveis:
- O período passado como parâmetro se encontra totalmente dentro de um período cadastrado na tabela;
- A data inicial passada como parâmetro se encontra dentro de um período cadastrado na tabela, mas a data final se encontra fora de um período cadastrado na tabela;
- A data final passada como parâmetro se encontra dentro de um período cadastrado na tabela, mas a data inicial se encontra fora de um período cadastrado na tabela;
- Tanto a data inicial quanto a data final passadas como parâmetro se encontram fora de qualquer período cadastrado na tabela, porém, existe um período cadastrado na tabela que compreende o período passado como parâmetro;
- Tanto a data inicial quanto a data final passadas como parâmetro se encontram fora de qualquer período cadastrado na tabela, e não existe nenhum período cadastrado na tabela que compreenda o período passado como parâmetro.
Segue exemplo de como contemplar todas estas possibilidades:
Declare @Tabela Table (ID int Identity, PeriodoInicial Date, PeriodoFinal Date, Temporada VarChar(20)) Insert Into @Tabela Values ('2012-07-01', '2012-07-31', 'Alta'), ('2012-12-15', '2012-12-31', 'Alta'), ('2013-01-01', '2013-01-31', 'Alta'), ('2013-02-09', '2013-02-12', 'Feriado') Declare @DataInicial Date, @DataFinal Date Set @DataInicial = '2012-12-20' Set @DataFinal = '2013-02-20' ;With CTE as ( Select Temporada, Dias = Case When (@DataInicial between PeriodoInicial and PeriodoFinal) and (@DataFinal between PeriodoInicial and PeriodoFinal) then DateDiff(dd, @DataInicial, @DataFinal) When (@DataInicial between PeriodoInicial and PeriodoFinal) and (@DataFinal > PeriodoFinal) then DateDiff(dd, @DataInicial, PeriodoFinal) When (@DataInicial < PeriodoInicial) and (@DataFinal between PeriodoInicial and PeriodoFinal) then DateDiff(dd, PeriodoInicial, @DataFinal) Else DateDiff(dd, PeriodoInicial, PeriodoFinal) End From @Tabela Where ((@DataInicial between PeriodoInicial and PeriodoFinal) and (@DataFinal between PeriodoInicial and PeriodoFinal)) or ((@DataInicial between PeriodoInicial and PeriodoFinal) and (@DataFinal > PeriodoFinal)) or ((@DataInicial < PeriodoInicial) and (@DataFinal between PeriodoInicial and PeriodoFinal)) or ((PeriodoInicial between @DataInicial and @DataFinal) and (PeriodoFinal between @DataInicial and @DataFinal)) ) Select Temporada, TotalDias = Sum(Dias) From CTE Group by Temporada
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.- Sugerido como Resposta Roberson Ferreira _ quarta-feira, 19 de setembro de 2012 17:26
- Marcado como Resposta BrunoZP quarta-feira, 19 de setembro de 2012 18:04
-
Bruno depois q entendi melhor a dúvida,
Segue uma nova sugestão:
--declarando uma tabela temporária declare @t as table (ID int, PeriodoInicial date, PeriodoFinal date, Temporada varchar(15) ) --populando a tabela insert into @t values (1,'2012-07-01 00:00:00.000','2012-07-31 00:00:00.000','Alta'), (2,'2012-12-15 00:00:00.000','2012-12-31 00:00:00.000','Alta'), (3,'2013-01-01 00:00:00.000','2013-01-31 00:00:00.000','Alta'), (4,'2013-02-09 00:00:00.000','2013-02-12 00:00:00.000','Feriado') -- Declarando parametros de entrada declare @dtIni as date , @dtFim as date --Setando valores aos paramentros select @dtIni = '2013-02-01', @dtFim = '2013-02-15' ;with cte_Dias (dia) as ( select @dtIni union all select DATEADD(D,1,dia) from cte_Dias where dia<@dtFim ) select COUNT(dia) as qtdDia from cte_Dias as c join @t as t on c.dia between t.PeriodoInicial and t.PeriodoFinal
Se a minha ajuda lhe for útil não esqueça de classificar. Att. Leonardo Marcelino
-
Roberson,
Você foi mais esperto que eu, pensei somente em analisar com base no Período:
Declare @Tabela Table (ID int Identity, PeriodoInicial Date, PeriodoFinal Date, Temporada VarChar(20)) Insert Into @Tabela Values ('2012-07-01', '2012-07-31', 'Alta'), ('2012-12-15', '2012-12-31', 'Alta'), ('2013-01-01', '2013-01-31', 'Alta'), ('2013-02-09', '2013-02-12', 'Feriado') Declare @DataInicial Date, @DataFinal Date Set @DataInicial = '2012-12-01' Set @DataFinal = '2013-02-28' Select Temporada, CONVERT(VarChar(7),periodoinicial,111)+' até '+CONVERT(VarChar(7),periodofinal,111) As Periodo, DATEDIFF(DD,PeriodoInicial, PeriodoFinal) As Dias from @Tabela Where (PeriodoInicial between @DataInicial and @DataFinal) Or (PeriodoFinal between @DataInicial and @DataFinal) Group By Temporada, PeriodoInicial,PeriodoFinal
Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]
-
Muito obrigado!
Só alterei o
Select Temporada, TotalDias = Sum(Dias) From CTE Group by Temporada
para
Select Temporada, TotalDias = Sum(Dias)+1 From CTE Group by Temporada
Pois o ultimo dia também deve ser considerado.
http://BrunoZP.com.br || http://BrunoZP.com
-
OK. Cheguei a imaginar isso, mas não tinha certeza.
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.