Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Połączenie zewnętrzne Oracle nie działa zgodnie z oczekiwaniami

Wygląda na to, że naprawdę chcesz dołączyć INNER. Upuść (+) i zobacz, czy odzyskasz to, czego szukasz. Ponadto @GordonLinoff daje doskonałą sugestię - poczuj się komfortowo z używaniem składni złączeń ANSI, która jest zarówno bardziej wyrazista, jak i bardziej zrozumiała niż stary styl „umieść wszystkie warunki w klauzuli WHERE, a następnie spróbuj rozwiązać problem” .

Oto jak przepisać to zapytanie przy użyciu standardowej składni złączenia 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'))

Jeszcze jedna drobna sprawa. Zauważyłem, że używasz BETWEEN z wartościami dat, co może być problematyczne. Załóżmy na przykład, że masz EFFECTIVE_START_DATE 01.01.2013 i EFFECTIVE_END_DATE 30.06.2013 w jakimś wierszu w PER_ALL_ASSIGNMENTS_F, a ponadto załóżmy, że aktualna data i godzina to 30.06.2013 o 07:02:04. Biorąc pod uwagę te wartości danych, ten wiersz z PER_ALL_ASSIGNMENTS_F NIE być wybrany, chociaż można by się tego spodziewać. Problem polega na tym, że gdy jedynymi polami wypełnianymi w wartości DATE są dzień, miesiąc i rok, to godzina, minuty i sekundy domyślnie wynoszą zero – zatem data końcowa to naprawdę 30 czerwca 2013 o godzinie 00:00:00, która jest wcześniejsza niż bieżąca data/godzina z dnia 30 czerwca 2013 o godzinie 07:02:04, a w konsekwencji porównanie dat powoduje zignorowanie wiersza. Nie wiem, w jaki sposób pola EFFECTIVE_END_DATE są wypełniane w Twojej bazie danych — mam nadzieję, że są całkowicie wypełnione, np. 30-JUN-2013 23:59:59 - ale jeśli nie, być może będziesz musiał dokonać porównania dat w stylu

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

lub

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

(Prawdopodobnie ta pierwsza jest lepszym wyborem, ponieważ druga forma wykluczy użycie jakiegokolwiek indeksu nieopartego na funkcjach, który może istnieć w dniu (EFFECTIVE_START_DATE, EFFECTIVE_END_DATE).

Dziel się i ciesz.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. zapytanie Oracle do porównania wszystkich wierszy o tym samym identyfikatorze w tabeli

  2. Zbieranie zbiorcze PL/SQL z klauzulą ​​LIMIT w bazie danych Oracle

  3. PLS-00201:identyfikator 'R_CUR' musi być zadeklarowany w dynamicznym sql

  4. Wstawianie tablicy byte[] jako obiektu BLOB w bazie danych Oracle Pobieranie ORA-01460:zażądano niewdrożonej lub nieuzasadnionej konwersji

  5. Grupuj Oracle część wiersza i uzyskaj wiersz z najnowszym znacznikiem czasu