Inquiridor
Calculo de intervalos de datas

Pergunta
-
Bom dia pessoal,
estou com uma grande dúvida em fazer um processo para cálculo de datas.
Tenho a seguinte experiência de um funcionário:
seq_rh cod_pessoa nom_rh ano_inicio mes_inicio ano_fim mes_fim ind_atividade_atual
68507 102747 Abel Antônio da Silva 1989 3 2013 5 ATUAL
68507 102747 Abel Antônio da Silva 1990 3 1991 12 ANTERIOR
68507 102747 Abel Antônio da Silva 1992 2 1993 12 ANTERIORGostaria de calcular o tempo de experiência do funcionário em meses considerando as intercessões.
Conforme calculado abaixo:
seq_rh cod_pessoa nom_rh ano_inicio mes_inicio ano_fim mes_fim ind_atividade_atual
68507 102747 Abel Antônio da Silva 1989 3 2013 5 ATUAL =26 meses
68507 102747 Abel Antônio da Silva 1990 3 1991 12 ANTERIOR =21 meses
68507 102747 Abel Antônio da Silva 1992 2 1993 12 ANTERIOR =22 mesesComo o intervalo das linhas 2 e 3 estão contidos no intervalo da linha 1 devemos considerar somente que o funcionário tem 26 meses de experiência.
Como fazer esse cálculo no SQL, uma vez que tenho que verificar estas intercessões?
Todas as Respostas
-
-
Vinycius01, bom dia !
Esta parte da quantidade de meses baseado no ano e mes é facil, veja abaixo a query, agora a parte que voce falou de intervalos não ficou muito claro, pode dar mais detalhes sobre qual a regra a ser aplicada ?
Segue a query para fazer a diferença sem intervalos:
Create table #temp (AnoInicio int, MesInicio Int, AnoFim int, mesFim int) insert into #temp values (1989,3,2013,5), (1990,3,1991,12), (1992,2,1993,12) select AnoInicio, MesInicio, AnoFim, mesFim, Tempo = Case when AnoInicio < AnoFim then ((AnoFim - AnoInicio) * 12) + (mesFim - MesInicio) When AnoInicio = AnoFim then (mesFim - MesInicio) end from #temp
Alexandre Matayosi Conde Mauricio.
-
A quantidade de dados é grande +/- uns 50000 registros de funcionários diferentes.
Sobre os intervalos perceba:
_ Na linha 1 o intervalo é de 3/1989 até 5/2013 deste modo as linhas 2(3/1990 até 12/1991) e 3 (2/1992 até 12/1993) estão contidas no intervalo da linha 1, ok?
Por isso devemos considerar apenas a quantidade de meses da linha 1 (26 meses).
O intuito é verificar qual intervalo de tempo esta contido em outro do mesmo funcionário. Se o intervalo estiver contido , considera-se o intervalo que o contém. Caso os intervalo sejam "quebrados" deve ser realizada a soma destes.
-
-
-
Veja como fiz:
SELECT t3.seq_rh, t3.cod_pessoa, t3.nom_rh, Sum(dif) Total_em_Anos_Exp_Graduacao FROM (SELECT DISTINCT t1.seq_rh, t1.cod_pessoa, t1.nom_rh, --t1.ano_inicio AS t1_ano_inicio, --t1.ano_fim AS t1_ano_fim, T1.ano_fim - T1.ano_inicio AS DIF /*t2.ano_inicio as t2_ano_inicio, t2.ano_fim as t2_ano_fim*/ FROM (SELECT rh.seq_rh, rh.cod_pessoa, rh.nom_rh, fa.ano_inicio, fa.mes_inicio, CASE WHEN Isnull(fa.ano_fim, '') <> '' AND fa.ano_inicio <= fa.ano_fim AND fa.ano_fim <> '0' AND fa.ano_fim <> 0 AND fa.ano_fim <> '' AND fa.ind_atividade_atual <> 'ATUAL' THEN fa.ano_fim ELSE Year(Getdate()) END AS ano_fim, CASE WHEN Isnull(fa.mes_fim, '') <> '' AND fa.mes_inicio <= fa.mes_fim AND fa.mes_fim <> '0' AND fa.mes_fim <> 0 AND fa.mes_fim <> '' AND fa.ind_atividade_atual <> 'ATUAL' THEN Month(Getdate()) ELSE fa.mes_fim END AS mes_fim, fa.ind_atividade_atual FROM cvl.dbo.recurso_humano AS rh LEFT OUTER JOIN cvl.dbo.funcao_atividade AS fa ON rh.seq_rh = fa.seq_rh AND fa.cod_natureza_atividade IN ( '401' )) T1, (SELECT rh.seq_rh, rh.cod_pessoa, rh.nom_rh, fa.ano_inicio, fa.mes_inicio, CASE WHEN Isnull(fa.ano_fim, '') <> '' AND fa.ano_inicio <= fa.ano_fim AND fa.ano_fim <> '0' AND fa.ano_fim <> 0 AND fa.ano_fim <> '' AND fa.ind_atividade_atual <> 'ATUAL' THEN fa.ano_fim ELSE Year(Getdate()) END AS ano_fim, CASE WHEN Isnull(fa.mes_fim, '') <> '' AND fa.mes_inicio <= fa.mes_fim AND fa.mes_fim <> '0' AND fa.mes_fim <> 0 AND fa.mes_fim <> '' AND fa.ind_atividade_atual <> 'ATUAL' THEN Month(Getdate()) ELSE fa.mes_fim END AS mes_fim, fa.ind_atividade_atual FROM cvl.dbo.recurso_humano AS rh LEFT OUTER JOIN cvl.dbo.funcao_atividade AS fa ON rh.seq_rh = fa.seq_rh AND fa.cod_natureza_atividade IN ( '401' )) T2 WHERE /*t1.nom_rh='Adriana Gomes Dickman' and t2.nom_rh='Adriana Gomes Dickman' and */ ( ( t1.ano_inicio NOT BETWEEN t2.ano_inicio AND t2.ano_fim ) AND ( t1.ano_fim NOT BETWEEN t2.ano_inicio AND t2.ano_fim ) ) --AND ( T2.ano_inicio= t1.ano_inicio AND t2.ano_fim= t1.ano_fim ) AND t1.cod_pessoa = T2.cod_pessoa --GROUP BY T1.nom_rh --ORDER BY t1.nom_rh EXCEPT SELECT DISTINCT t1.seq_rh, t1.cod_pessoa, t1.nom_rh, --t1.ano_inicio AS t1_ano_inicio, --t1.ano_fim AS t1_ano_fim, T1.ano_fim - T1.ano_inicio AS DIF /*, t2.ano_inicio as t2_ano_inicio, t2.ano_fim as t2_ano_fim*/ FROM (SELECT rh.seq_rh, rh.cod_pessoa, rh.nom_rh, fa.ano_inicio, fa.mes_inicio, CASE WHEN Isnull(fa.ano_fim, '') <> '' AND fa.ano_inicio <= fa.ano_fim AND fa.ano_fim <> '0' AND fa.ano_fim <> 0 AND fa.ano_fim <> '' AND fa.ind_atividade_atual <> 'ATUAL' THEN fa.ano_fim ELSE Year(Getdate()) END AS ano_fim, CASE WHEN Isnull(fa.mes_fim, '') <> '' AND fa.mes_inicio <= fa.mes_fim AND fa.mes_fim <> '0' AND fa.mes_fim <> 0 AND fa.mes_fim <> '' AND fa.ind_atividade_atual <> 'ATUAL' THEN Month(Getdate()) ELSE fa.mes_fim END AS mes_fim, fa.ind_atividade_atual FROM cvl.dbo.recurso_humano AS rh LEFT OUTER JOIN cvl.dbo.funcao_atividade AS fa ON rh.seq_rh = fa.seq_rh AND fa.cod_natureza_atividade IN ( '401' )) T1, (SELECT rh.seq_rh, rh.cod_pessoa, rh.nom_rh, fa.ano_inicio, fa.mes_inicio, CASE WHEN Isnull(fa.ano_fim, '') <> '' AND fa.ano_inicio <= fa.ano_fim AND fa.ano_fim <> '0' AND fa.ano_fim <> 0 AND fa.ano_fim <> '' AND fa.ind_atividade_atual <> 'ATUAL' THEN fa.ano_fim ELSE Year(Getdate()) END AS ano_fim, CASE WHEN Isnull(fa.mes_fim, '') <> '' AND fa.mes_inicio <= fa.mes_fim AND fa.mes_fim <> '0' AND fa.mes_fim <> 0 AND fa.mes_fim <> '' AND fa.ind_atividade_atual <> 'ATUAL' THEN Month(Getdate()) ELSE fa.mes_fim END AS mes_fim, fa.ind_atividade_atual FROM cvl.dbo.recurso_humano AS rh LEFT OUTER JOIN cvl.dbo.funcao_atividade AS fa ON rh.seq_rh = fa.seq_rh AND fa.cod_natureza_atividade IN ( '401' )) T2 WHERE /*t1.nom_rh='Adriana Gomes Dickman' and t2.nom_rh='Adriana Gomes Dickman' and */ ( ( t1.ano_inicio BETWEEN t2.ano_inicio AND t2.ano_fim ) AND ( t1.ano_fim BETWEEN t2.ano_inicio AND t2.ano_fim ) ) AND ( ( T2.ano_inicio <> t1.ano_inicio ) OR ( t2.ano_fim <> t1.ano_fim ) ) AND t1.cod_pessoa = T2.cod_pessoa --GROUP BY T1.nom_rh, T1.ano_fim, T1.ano_inicio )T3 GROUP BY t3.seq_rh, t3.cod_pessoa, t3.nom_rh ORDER BY T3.nom_rh
-
-
-
Sim.
Obrigado pela referencia.
Vc formou esp. em banco de dados pela PUC Minas? Gostou do curso?
Eu faço esp. em Banco de dados no CEFET-MG...
- Editado vinycius01 terça-feira, 14 de maio de 2013 18:53