Oracle
 sql >> Base de données >  >> RDS >> Oracle

La jointure externe Oracle ne fonctionne pas comme prévu

On dirait que ce que vous voulez vraiment, c'est une jointure INNER. Laissez tomber les (+) et voyez si vous récupérez ce que vous cherchez. De plus, @GordonLinoff fait une excellente suggestion - familiarisez-vous avec l'utilisation de la syntaxe de jointure ANSI, qui est à la fois plus expressive et plus compréhensible que l'ancien style "mettez toutes les conditions dans la clause WHERE, puis essayez de résoudre le problème". .

Voici comment je réécrirais cette requête en utilisant la syntaxe de jointure standard 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'))

Une autre question mineure. Je remarque que vous utilisez BETWEEN avec des valeurs de date qui peuvent potentiellement poser problème. Disons, par exemple, que vous avez un EFFECTIVE_START_DATE du 01-JAN-2013 et un EFFECTIVE_END_DATE du 30-JUN-2013 sur une ligne dans PER_ALL_ASSIGNMENTS_F, et disons en outre que la date et l'heure actuelles sont le 30-JUN-2013 à 07:02:04. Compte tenu de ces valeurs de données, cette ligne de PER_ALL_ASSIGNMENTS_F ne sera PAS être sélectionné, bien que vous puissiez vous attendre à ce qu'il le soit. Le problème est que lorsque les seuls champs remplis sur une valeur DATE sont le jour, le mois et l'année, l'heure, les minutes et les secondes sont par défaut à zéro ; la date de fin est donc vraiment 30-JUN-2013 à 00:00:00, ce qui est antérieur à la date/heure actuelle du 30-JUN-2013 à 07:02:04 AM, et par conséquent la comparaison de dates entraîne l'ignorance de la ligne. Je ne sais pas comment les champs EFFECTIVE_END_DATE sont remplis dans votre base de données. J'espère qu'ils sont complètement remplis, par exemple. 30-JUN-2013 23:59:59 - mais si ce n'est pas le cas, vous devrez peut-être faire quelque chose comme la comparaison de dates

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

(La première forme est probablement un meilleur choix, car la seconde forme empêchera l'utilisation de tout index non basé sur une fonction qui pourrait exister le (EFFECTIVE_START_DATE, EFFECTIVE_END_DATE).

Partagez et profitez.