sql >> Databasteknik >  >> RDS >> Oracle

Oracle yttre koppling fungerar inte som förväntat

Det låter som att det du verkligen vill ha är en INNER join. Släpp (+) och se om du får tillbaka det du letar efter. Dessutom ger @GordonLinoff ett utmärkt förslag - gör dig bekväm med att använda ANSI join-syntaxen, som är både mer uttrycksfull och mer begriplig än den gamla stilen "lägg alla villkor i WHERE-satsen och försök sedan pussla ut det"-stilen .

Så här skulle jag skriva om den här frågan med ANSI-standardsyntaxen:

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'))

En annan mindre sak. Jag märker att du använder BETWEEN med datumvärden som potentiellt kan vara problematiska. Låt oss till exempel säga att du har en EFFECTIVE_START_DATE 01-JAN-2013 och en EFFECTIVE_END_DATE av 30-JUN-2013 på någon rad i PER_ALL_ASSIGNMENTS_F, och låt oss vidare säga att det aktuella datumet och tiden är 30-3 JUN-2013 klockan 07:02:04. Med tanke på dessa datavärden kommer den här raden från PER_ALL_ASSIGNMENTS_F INTE att väljas, även om du kanske förväntar dig att det blir det. Problemet är att när de enda fälten som fylls i på ett DATUM-värde är dagen, månaden och året, så är timmen, minuterna och sekunderna som standard noll - så slutdatumet är verkligen 30-JUN-2013 kl. 00:00:00, vilket är före det aktuella datumet/tiden den 30-JUN-2013 kl. 07:02:04, och följaktligen gör datumjämförelsen att raden ignoreras. Jag vet inte hur EFFECTIVE_END_DATE-fälten är ifyllda i din databas - förhoppningsvis är de helt ifyllda, t.ex. 30-JUN-2013 23:59:59 - men om inte kan du behöva göra din datumjämförelse något liknande

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

eller

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

(Den förra är förmodligen ett bättre val, eftersom den senare formen utesluter användningen av något icke-funktionsbaserat index som kan existera på (EFFECTIVE_START_DATE, EFFECTIVE_END_DATE).

Dela och njut.



  1. PSQLEundantag:denna resultatuppsättning är stängd

  2. Hur kan vi återanvända det borttagna ID:t från någon MySQL-DB-tabell?

  3. 3 sätt att kontrollera en kolumns datatyp i PostgreSQL

  4. Gruppera mysql-fråga med 15 minuters intervall