sql >> Databáze >  >> RDS >> Oracle

Vnější spojení Oracle nefunguje podle očekávání

Zní to, že to, co opravdu chcete, je VNITŘNÍ spojení. Zahoďte (+) a uvidíte, zda se vám vrátí to, co hledáte. Kromě toho nabízí @GordonLinoff vynikající návrh – zorientujte se v používání syntaxe spojení ANSI, která je výraznější a srozumitelnější než starý styl „vložte všechny podmínky do klauzule WHERE a pak to zkuste rozluštit“ .

Zde je návod, jak bych tento dotaz přepsal pomocí syntaxe spojení podle standardu 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'))

Ještě jedna drobná záležitost. Všiml jsem si, že používáte BETWEEN s hodnotami data, což může být potenciálně problematické. Řekněme například, že na některém řádku v PER_ALL_ASSIGNMENTS_F máte EFFECTIVE_START_DATE 01-JAN-2013 a EFFECTIVE_END_DATE 30-JUN-2013, a dále řekněme, že aktuální datum a čas je 30-JUN-2013 v 07:02:04. Vzhledem k těmto hodnotám dat tento řádek z PER_ALL_ASSIGNMENTS_F NEBUDE být vybrán, i když byste to mohli očekávat. Problém je v tom, že když jsou jedinými poli vyplněnými v hodnotě DATE den, měsíc a rok, pak jsou hodiny, minuty a sekundy ve výchozím nastavení nula – takže datum ukončení je skutečně 30-JUN-2013 v 00:00:00, což je před aktuálním datem/časem 30-JUN-2013 v 07:02:04 AM, a následně porovnání data způsobí, že bude řádek ignorován. Nevím, jak jsou pole EFFECTIVE_END_DATE ve vaší databázi vyplněna – doufám, že jsou zcela vyplněna, např. 30-JUN-2013 23:59:59 – ale pokud ne, možná budete muset provést srovnání dat jako

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

nebo

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

(První forma je pravděpodobně lepší volbou, protože druhá forma bude bránit použití jakéhokoli indexu nezaloženého na funkcích, který může existovat dne (EFFECTIVE_START_DATE, EFFECTIVE_END_DATE).

Sdílejte a užívejte si.



  1. Jak nastavit řazení pomocí mysqli?

  2. Doporučené postupy replikace MySQL

  3. Optimalizace indexu tabulky MySQL

  4. Návrh databáze 101:Oddíly v MySQL