Oracle
 sql >> база данни >  >> RDS >> Oracle

Външното присъединяване на Oracle не работи според очакванията

Звучи сякаш това, което наистина искате, е ВЪТРЕШНО присъединяване. Пуснете (+) и вижте дали ще получите това, което търсите. В допълнение, @GordonLinoff прави отлично предложение - научете се да използвате ANSI синтаксиса за присъединяване, който е едновременно по-изразителен и по-разбираем от стария стил "поставете всички условия в клаузата WHERE и след това се опитайте да го разгадаете" .

Ето как бих пренаписал тази заявка, използвайки 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'))

Още един незначителен въпрос. Забелязвам, че използвате BETWEEN със стойности на дата, което потенциално може да бъде проблематично. Да кажем, например, че имате EFFECTIVE_START_DATE от 01-JAN-2013 и EFFECTIVE_END_DATE от 30-JUN-2013 на някой ред в PER_ALL_ASSIGNMENTS_F и нека освен това кажем, че текущите дата и час са 30-JUN-2013 в 07:02:04ч. Като се имат предвид тези стойности на данните, този ред от PER_ALL_ASSIGNMENTS_F НЯМА бъде избран, въпреки че може да очаквате да бъде избран. Проблемът е, че когато единствените полета, попълнени в стойността на ДАТА, са ден, месец и година, тогава часът, минутите и секундите по подразбиране са нула - следователно крайната дата е наистина 30-ЮНИ-2013 г. в 00:00:00 ч., което е преди текущата дата/час на 30-ЮНИ-2013 г. в 07:02:04 ч., и следователно сравнението на дати кара реда да бъде игнориран. Не знам как се попълват полетата EFFECTIVE_END_DATE във вашата база данни - надявам се, че са напълно попълнени, напр. 30-ЮНИ-2013 23:59:59 - но ако не, може да се наложи да направите сравнението на датите си нещо като

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

или

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

(Първата вероятно е по-добър избор, тъй като втората форма ще изключи използването на не-функционален индекс, който може да съществува на (EFFECTIVE_START_DATE, EFFECTIVE_END_DATE).

Споделяйте и се наслаждавайте.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изпълнение на Total от Group SQL (Oracle)

  2. SQLPlus - спулиране към множество файлове от PL/SQL блокове

  3. PL/SQL процедура/функция за динамично показване на данни от различни таблици заедно с имената на колоните в първия ред с данни

  4. Oracle Data Access FileNotFound:Oracle.DataAccess.Common.Configuration.Section.xsd

  5. предимството на използването на тригер за попълване на сурогатен ключ в oracle plsql