sql >> Base de Datos >  >> RDS >> Oracle

La unión externa de Oracle no funciona como se esperaba

Parece que lo que realmente quieres es una unión INTERNA. Suelta los (+) y mira si obtienes lo que estás buscando. Además, @GordonLinoff hace una sugerencia excelente:familiarícese con el uso de la sintaxis de combinación ANSI, que es más expresiva y más comprensible que el estilo antiguo "ponga todas las condiciones en la cláusula WHERE y luego intente resolverlo". .

Así es como reescribiría esta consulta usando la sintaxis de combinación estándar 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'))

Otro asunto menor. Me doy cuenta de que está utilizando BETWEEN con valores de fecha que pueden ser potencialmente problemáticos. Digamos, por ejemplo, que tiene un EFFECTIVE_START_DATE de 01-ENE-2013 y un EFFECTIVE_END_DATE de 30-JUN-2013 en alguna fila en PER_ALL_ASSIGNMENTS_F, y digamos además que la fecha y la hora actuales son 30-JUN-2013 a las 07:02:04 a.m. Dados estos valores de datos, esta fila de PER_ALL_ASSIGNMENTS_F NO ser seleccionado, aunque usted podría esperar que lo sea. El problema es que cuando los únicos campos que se rellenan en un valor de FECHA son el día, el mes y el año, la hora, los minutos y los segundos se establecen de forma predeterminada en cero, por lo que la fecha de finalización es realmente. 30-JUN-2013 a las 00:00:00, que es anterior a la fecha/hora actual de 30-JUN-2013 a las 07:02:04 AM y, en consecuencia, la comparación de fechas hace que se ignore la fila. No sé cómo se llenan los campos EFFECTIVE_END_DATE en su base de datos; espero que estén completamente llenos, p. 30-JUN-2013 23:59:59 - pero si no es así, es posible que deba hacer su comparación de fechas algo así

TRUNC(SYSDATE) BETWEEN paaf.EFFECTIVE_START_DATE
                   AND paaf.EFFECTIVE_END_DATE

o

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

(La primera es probablemente una mejor opción, ya que la última forma impedirá el uso de cualquier índice no basado en funciones que pueda existir el (EFFECTIVE_START_DATE, EFFECTIVE_END_DATE).

Comparte y disfruta.