Filtrar maior validade

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
victor.zero
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 3
Registrado em: Seg, 02 Mai 2016 9:09 am

Bom dia a todos,
Gostaria de uma ajuda com esse select, estou tentando filtrar a maior data de validade de 3 tipos de documentos.

Selecionar tudo

SELECT
         A.CODIGOVEIC
        ,A.CODIGOEMPRESA
        ,A.CODIGOFL
        ,A.PREFIXOVEIC
        ,A.PLACAATUALVEIC
        ,B.DESCRICAOTPVEIC
        ,C.DESCRICAOTPFROTA
        ,D.CODIGOTPDOC
        ,D.NUMERODOC
        ,E.DESCRICAOTPDOC
        ,F.VALIDADEVISTORIA
        
FROM
         FRT_CADVEICULOS        A
        ,FRT_TIPODEVEICULO     B
        ,FRT_TIPODEFROTA        C   
        ,DVS_DOCUMENTO          D
        ,DVS_TIPODOCTO           E
        ,DVS_VISTORIA               F  
WHERE
            A.CODIGOVEIC              =     624
AND      A.CODIGOTPVEIC          =     B.CODIGOTPVEIC
AND      A.CODIGOTPFROTA      =     C.CODIGOTPFROTA
AND      A.CODIGOVEIC             =     D.CODIGOVEIC
AND      D.CODIGOTPDOC          =     E.CODIGOTPDOC
AND      D.NUMERODOC             =     F.NUMERODOC
AND      D.CODIGOTPDOC          IN     (00014,00015,00016)
Obs. Esse documentos tem renovação periódica, portanto toda vez que um documento é renovado tenho que cadastra-lo novamente pois alem da data de validade sua numeração também muda.
Ex.

1 - 624 - 2 - 1 - 0003279 - AAA-9999 - CAVALO MECANICO - FROTA A - 00015 - 0519052 - CIV - 30/04/2016
2 - 624 - 2 - 1 - 0003279 - AAA-9999 - CAVALO MECANICO - FROTA A - 00015 - 0520055 - CIV - 25/05/2016

O resultado do select é esse preciso que retorne somente o 2 registro pois sua validade é maior.
spernega
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Ter, 19 Jun 2007 2:12 pm
Localização: São Paulo - SP

Boa tarde Vitor,

Tente usar o Greatest ( data1 , data2, data3, ...)
victor.zero
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 3
Registrado em: Seg, 02 Mai 2016 9:09 am

Bom dia

E como ficaria nesse select, pois nuca usei o GREATEST.
spernega
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Ter, 19 Jun 2007 2:12 pm
Localização: São Paulo - SP

Bom dia Victor,

O Greatest serve para retornar a maior data, ou maior valor, dentro de uma série de informações.
Ex.
Select greatest(dt_cadastro, dt_alteracao, dt_consulta) maior_datafrom tabela;
Select greatest(1,2,3) maior_numero from dual;

obs: para retornar o menor valor você usaria o LEAST, da mesma forma.

No caso da sua pesquisa, se entendi bem, você quer que retorne apenas o registro com a maior data.

Uma alternativa é usar uma subquery:

Selecionar tudo

SELECT   A.CODIGOVEIC
        ,A.CODIGOEMPRESA
        ,A.CODIGOFL
        ,A.PREFIXOVEIC
        ,A.PLACAATUALVEIC
        ,B.DESCRICAOTPVEIC
        ,C.DESCRICAOTPFROTA
        ,D.CODIGOTPDOC
        ,D.NUMERODOC
        ,E.DESCRICAOTPDOC
        --
        ,F.VALIDADEVISTORIA
        -- 
FROM     FRT_CADVEICULOS   A
        ,FRT_TIPODEVEICULO B
        ,FRT_TIPODEFROTA   C   
        ,DVS_DOCUMENTO     D
        ,DVS_TIPODOCTO     E
        ,DVS_VISTORIA      F  
        --
WHERE   F.VALIDADEVISTORIA = (SELECT MAX(F.VALIDADEVISTORIA) 
                              FROM     FRT_CADVEICULOS   A
                                      ,FRT_TIPODEVEICULO B
                                      ,FRT_TIPODEFROTA   C   
                                      ,DVS_DOCUMENTO     D
                                      ,DVS_TIPODOCTO     E
                                      ,DVS_VISTORIA      F  
                              WHERE   A.CODIGOVEIC      =     624
                              AND     A.CODIGOTPVEIC    =     B.CODIGOTPVEIC
                              AND     A.CODIGOTPFROTA   =     C.CODIGOTPFROTA
                              AND     A.CODIGOVEIC      =     D.CODIGOVEIC
                              AND     D.CODIGOTPDOC     =     E.CODIGOTPDOC
                              AND     D.NUMERODOC       =     F.NUMERODOC
                              AND     D.CODIGOTPDOC     IN     (00014,00015,00016))
         --
AND      A.CODIGOVEIC      =     624
AND      A.CODIGOTPVEIC    =     B.CODIGOTPVEIC
AND      A.CODIGOTPFROTA   =     C.CODIGOTPFROTA
AND      A.CODIGOVEIC      =     D.CODIGOVEIC
AND      D.CODIGOTPDOC     =     E.CODIGOTPDOC
AND      D.NUMERODOC       =     F.NUMERODOC
AND      D.CODIGOTPDOC     IN     (00014,00015,00016)
esta subquery pode ser reduzida, esta um pouco grande pois não conheço a estrutura das tabela, poderia excluir as tabela descritivas por exemplo.

Outra, você poderia abrir um cursor ordenado por VALIDADEVISTORIA decrescente e sair do cursor após o fetch do primeiro retorno.
Depende de como você vai trabalhar.

Espero ter ajudado.
victor.zero
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 3
Registrado em: Seg, 02 Mai 2016 9:09 am

Obrigado pela ajuda, meu select ficou assim,

Selecionar tudo

SELECT
       A.CODIGOVEIC               CODVEIC
      ,A.CODIGOEMPRESA            EMP
      ,A.CODIGOFL                 FIL
      ,A.PREFIXOVEIC              PREFIXO
      ,A.PLACAATUALVEIC           PLACA
      ,A.CODIGOTPVEIC             CODTPVEI
      ,B.DESCRICAOTPVEIC          TIPOVEICULO
      ,A.CODIGOTPFROTA            CODTPFRT
      ,C.DESCRICAOTPFROTA         TIPOFROTA
      ,D.CODIGOTPDOC              CODTPDOC
      ,E.DESCRICAOTPDOC           DOCUMENTO
      ,D.NUMERODOC                NUMERO
      ,F.VALIDADEVISTORIA         VALIDADE
      ,F.OBSERVACAOVISTORIA       OBS
FROM
       FRT_CADVEICULOS       A
      ,FRT_TIPODEVEICULO     B
      ,FRT_TIPODEFROTA       C
      ,DVS_DOCUMENTO         D
      ,DVS_TIPODOCTO         E
      ,DVS_VISTORIA          F
WHERE
      F.VALIDADEVISTORIA = (
                            SELECT
                                  MAX(G.VALIDADEVISTORIA)
                            FROM
                                  DVS_VISTORIA G
                            WHERE
                                  G.CODIGOTPDOC = D.CODIGOTPDOC
                            AND   G.CODIGOVEIC = F.CODIGOVEIC                      
                           )                                                                
 AND  A.CONDICAOVEIC     =    'A'
 AND  A.CODIGOTPVEIC     =    B.CODIGOTPVEIC
 AND  A.CODIGOTPFROTA    =    C.CODIGOTPFROTA
 AND  D.CODIGOVEIC       =    A.CODIGOVEIC
 AND  D.CODIGOTPDOC      =    E.CODIGOTPDOC
 AND  D.NUMERODOC        =    F.NUMERODOC
 AND  D.CODIGOTPDOC      =    F.CODIGOTPDOC
 AND  D.CODIGOTPDOC      IN   ('00004','00015','00016')
 AND  F.VALIDADEVISTORIA >=   (SYSDATE - 100000)
 AND  F.VALIDADEVISTORIA <=   (SYSDATE + 30)
ORDER BY
      F.VALIDADEVISTORIA
dessa forma ficou do jeito que eu queria.
Responder
  • Informação
  • Quem está online

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