Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

A junção externa do Oracle não está funcionando conforme o esperado


Parece que o que você realmente quer é uma junção INNER. Solte os (+) e veja se você recebe de volta o que está procurando. Além disso, @GordonLinoff faz uma excelente sugestão - fique à vontade com o uso da sintaxe de junção ANSI, que é mais expressiva e mais compreensível do que o estilo antigo "coloque todas as condições na cláusula WHERE e tente decifrá-la" .

Veja como eu reescreveria essa consulta usando a sintaxe de junção padrão ANSI:
SELECT *
  FROM PER_ALL_ASSIGNMENTS_F paaf
  INNER JOIN PAY_ALL_PAYROLLS_F payr
    ON payr.PAYROLL_ID = paaf.PAYROLL_ID
  WHERE SYSDATE BETWEEN paaf.EFFECTIVE_START_DATE
                    AND paaf.EFFECTIVE_END_DATE AND
        paaf.ASSIGNMENT_TYPE IN ('E', 'C') AND
        paaf.PRIMARY_FLAG = 'Y' AND
        payr.ATTRIBUTE1 = 'TINT' AND
        paaf.EFFECTIVE_START_DATE BETWEEN NVL(payr.EFFECTIVE_START_DATE, TO_DATE('01/01/1000', 'DD/MM/YYYY')) 
                                      AND NVL(payr.EFFECTIVE_END_DATE, TO_DATE('31/12/4712', 'DD/MM/YYYY'))

Um outro assunto menor. Percebo que você está usando BETWEEN com valores de data que podem ser potencialmente problemáticos. Digamos, por exemplo, que você tenha um EFFECTIVE_START_DATE de 01-JAN-2013 e um EFFECTIVE_END_DATE de 30-JUN-2013 em alguma linha em PER_ALL_ASSIGNMENTS_F, e digamos ainda que a data e hora atuais são 30-JUN-2013 às 07:02:04. Dados esses valores de dados, esta linha de PER_ALL_ASSIGNMENTS_F NÃO ser selecionado, embora você possa esperar que seja. O problema é que quando os únicos campos preenchidos em um valor DATE são o dia, mês e ano, a hora, os minutos e os segundos são padronizados para zero - portanto, a data final é realmente 30-JUN-2013 às 00:00:00, que é anterior à data/hora atual de 30-JUN-2013 às 07:02:04 AM e, consequentemente, a comparação de datas faz com que a linha seja ignorada. Não sei como os campos EFFECTIVE_END_DATE são preenchidos em seu banco de dados - espero que estejam completamente preenchidos, por exemplo, 30-JUN-2013 23:59:59 - mas se não você pode precisar fazer sua comparação de datas algo como
TRUNC(SYSDATE) BETWEEN paaf.EFFECTIVE_START_DATE
                   AND paaf.EFFECTIVE_END_DATE

ou
SYSDATE BETWEEN paaf.EFFECTIVE_START_DATE
            AND paaf.EFFECTIVE_END_DATE + INTERVAL '1' DAY - INTERVAL '1' SECOND

(O primeiro é provavelmente uma escolha melhor, pois o último formulário impedirá o uso de qualquer índice não baseado em função que possa existir em (EFFECTIVE_START_DATE, EFFECTIVE_END_DATE).

Compartilhe e curta.