RETORNANDO PERÍODOS

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
rfeitosa
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 2
Registrado em: Qua, 23 Abr 2008 4:23 pm
Localização: Guarulhos - SP
----------------------
Rafael Feitosa

Galera,

estou com um problema e gostaria da ajuda de vocês.

Tenho uma tabela onde estarão indicadas todas as entradas e saídas de um cliente dos nossos serviços:


TAB_MOV_SERVICOS(
ID INTEGER,
DATA_OCORRENCIA DATE,
TIPO VARCHAR2(3))


o campo tipo será sempre IN ou OUT (entrada ou saída). Até aí normal, porém preciso retornar sempre os períodos em que ele era assinante dos serviços, elaborei a query abaixo:


SELECT
OUT.ID AS ID,
NVL(IN.DATA_OCORRENCIA,TO_DATE('01-09-2002 00:00:00','DD-MM-YYYY HH24:MI:SS')) AS DATA_DE,
OUT.DATA_OCORRENCIA AS DATA_ATE
FROM
(SELECT * FROM TAB_MOV_SERVICOS WHERE TIPO='OUT') OUT,
(SELECT * FROM TAB_MOV_SERVICOS WHERE TIPO='IN') IN
WHERE OUT.ID=IN.ID(+)
AND OUT.DATA_OCORRENCIA >= IN.DATA_OCORRENCIA (+)

UNION

SELECT
OUT.ID AS ID,
IN.DATA_OCORRENCIA AS DATA_DE,
NVL(OUT.DATA_OCORRENCIA,SYSDATE) AS DATA_ATE
FROM
(SELECT * FROM TAB_MOV_SERVICOS WHERE TIPO='OUT') OUT,
(SELECT * FROM TAB_MOV_SERVICOS WHERE TIPO='IN') IN
WHERE OUT.ID(+)=IN.ID
AND OUT.DATA_OCORRENCIA (+) >= IN.DATA_OCORRENCIA


ela funciona perfeitamente, com exceção da seguinte situação:

suponhamos que eu tenha a linha do tempo com as ocorrências abaixo

-|--------------|-------------------------------|---------------|-----
IN OUT IN OUT
01/01/06 01/05/06 10/04/07 03/04/08

a query me retorna, além dos dois períodos um terceiro, que contempla de 01/01/06 até 03/04/08, o que está errado...

Alguém sabe como resolver?!

Obrigado!!!!
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Para este tipo de query, seria melhor utilizar funções analíticas, se possível, para acessar os valores do próximo registro e do registro anterior, facilitado a determinação da data inicial e final de cada evento.

Uma outra forma de escrever esta consulta seria:

Selecionar tudo

select id, entrada, nvl(saida, 'AINDA NÃO SAIU') saida
from
(
  select ms.id
       , ms.data_ocorrencia entrada
       , decode( tipo
               , 'IN' , decode( lead(ms.tipo, 1, 'OUT') over (partition by id order by data_ocorrencia asc)
                              , 'OUT', to_char(lead(ms.data_ocorrencia, 1, null) over (partition by id order by data_ocorrencia asc), 'dd/mm/yyyy hh24:mi:ss')
                              , 'IN' , 'SAÍDA INDETERMINADA'
                              )
               , 'OUT', decode( lag (ms.tipo, 1, 'OUT') over (partition by id order by data_ocorrencia asc)
                              , 'IN' , to_char(lead(ms.data_ocorrencia, 1, null) over (partition by id order by data_ocorrencia asc), 'dd/mm/yyyy hh24:mi:ss')
                              , 'OUT', 'ENTRADA INDETERMINADA'
                              )
               ) saida
       , ms.tipo
  from tab_mov_servicos ms
)
where tipo  = 'IN'
or    saida = 'ENTRADA INDETERMINADA'
rfeitosa
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 2
Registrado em: Qua, 23 Abr 2008 4:23 pm
Localização: Guarulhos - SP
----------------------
Rafael Feitosa

Rafael,

Muito obrigado pela dica, vou fazer os testes aqui e ver como ficará.

Abraços
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 5 visitantes