2011-08-25 17 views
6

Sto cercando di convertire una query Informix a Oracle:Unione di tabelle in Oracle (più join esterni)

La query Informix assomiglia a questo:

SELECT 
    r.aa, n.bb, nd.cc,u.id, ud.dd, g.attr 
FROM 
    tab1 u, tab2 ud, 
OUTER (tab3 a, tab4 n, tab5 nd, tab6 r, OUTER (tab7 g, tab8 atr)) 
WHERE 
    r.xx = n.xx AND 
    n.nas = a.nas AND 
    a.user = u.user AND 
    a.ac = g.ac AND 
    n.nas1 = nd.nas1 AND 
    u.user1 = ud.user1 AND 
    atr.sso = g.sso AND 
    UPPER(atr.name) = 'NAME' AND 
    u.id = 102 

La query di Oracle si presenta così:

SELECT 
    r.aa, n.bb, nd.cc,u.id, ud.dd, g.attr 
FROM 
    tab1 u 
INNER JOIN tab2 ud ON 
    u.user1 = ud.user1 AND 
    u.id = 102 
LEFT OUTER JOIN tab3 a ON a.user = u.user 
LEFT OUTER JOIN tab4 n ON n.nas = a.nas 
LEFT OUTER JOIN tab5 nd ON n.nas1 = nd.nas1 
LEFT OUTER JOIN tab6 r ON r.xx = n.xx 

Non sono sicuro di come unire gli altri due tavoli.

Qualcuno può aiutarmi?

+0

Che cosa significa la sintassi Informax? –

+0

Hai provato [SQLine] (http://www.sqlines.com/online)? –

risposta

0

vorrei provare l'aggiunta di questi:

LEFT OUTER JOIN tab7 g ON a.ac = g.ac 
LEFT OUTER JOIN tab8 atr ON g.sso = atr.sso AND UPPER(atr.name) = 'NAME' 
+0

Le tabelle tab7 e tab8 sono interlacciate l'una all'altra; il risultato composito è esterno unito alle altre tabelle. –

+0

'AND upper (atr.name)' rimuoverà la natura esterna sinistra del join. – Ben

7

Credo che la query dovrebbe essere simile a questa:

SELECT r.aa, n.bb, nd.cc, u.id, ud.dd, g.attr 
    FROM   tab1 AS u 
     INNER JOIN tab2 AS v ON u.user1 = v.user1 AND u.id = 102 
    LEFT OUTER JOIN tab3 AS a ON a.user = u.user 
    LEFT OUTER JOIN tab4 AS n ON n.nas = a.nas 
    LEFT OUTER JOIN tab5 AS d ON n.nas1 = d.nas1 
    LEFT OUTER JOIN tab6 AS r ON r.xx = n.xx 
    LEFT OUTER JOIN (SELECT g.attr, g.ac 
        FROM tab7 AS x 
        JOIN tab8 AS atr ON x.sso = atr.sso 
        WHERE UPPER(atr.name) = 'NAME' 
       ) AS g ON a.ac = g.ac 

ho cambiato l'alias 'nd' a solo 'D' e 'ud' a 'v' in modo che tutti gli alias siano a lettere singole. Il nidificato OUTER(tab7 g, tab8 atr) nella notazione Informix è di per sé un inner join (come nella sottoselezione nella mia versione), ma quel set di risultati è esterno unito a a.ac. Questo è ciò che dice la riscrittura.

Ho usato una clausola WHERE nella sottoquery; la condizione WHERE potrebbe essere lasciata nella clausola ON se si preferisce. È probabile che l'ottimizzatore gestirà sia correttamente che in modo equivalente. Allo stesso modo, lo AND u.id = 102 nel join interno potrebbe essere inserito in una clausola WHERE. Anche in questo caso, l'ottimizzatore probabilmente spingerebbe verso il basso le condizioni del filtro per ottenere prestazioni migliori.

Si noti che la funzione UPPER nella sottoquery richiede probabilmente una scansione della tabella, a meno che non si disponga di un indice funzionale su UPPER(atr.name).


Rivisitare questo, la traslitterazione della parte iniziale della query non è esatto.

La query originale includeva la clausola FROM:

FROM tab1 u, tab2 ud, OUTER(tab3 a, tab4 n, tab5 nd, tab6 r, OUTER(tab7 g, tab8 atr)) 

Le tabelle tab3, tab4, tab5 e tab6 sono interno incollati l'uno all'altro, e il risultato è esterno incollati a tab1 e tab2. Allo stesso modo, tab8 è interno-unito a tab7, ma il risultato è esterno-unito al inner-join delle tabelle 3-6. La risposta originale ho dato (in base alla risposta contorno in questione) sarebbe rappresentato nella vecchia notazione Informix utilizzando:

FROM tab1 u, tab2 ud, 
    OUTER(tab3 a, OUTER(tab4 n, OUTER(tab5 nd, OUTER(tab6 r, OUTER(tab7 g, tab8 atr))))) 

Quindi, sarebbe più esatto per trascrivere la query originale come:

SELECT r.aa, n.bb, nd.cc, u.id, ud.dd, g.attr 
    FROM tab1 AS u 
    JOIN tab2 AS v ON u.user1 = v.user1 AND u.id = 102 
    LEFT OUTER JOIN 
     (SELECT * 
      FROM tab3 AS a ON a.user = u.user 
      JOIN tab4 AS n ON n.nas = a.nas 
      JOIN tab5 AS d ON n.nas1 = d.nas1 
      JOIN tab6 AS r ON r.xx = n.xx 
      LEFT OUTER JOIN 
       (SELECT g.attr, g.ac 
       FROM tab7 AS x 
       JOIN tab8 AS atr ON x.sso = atr.sso 
       WHERE UPPER(atr.name) = 'NAME' 
       ) AS g ON a.ac = g.ac 
     ) AS loj 

Il problema residuo è garantire che gli alias corretti siano utilizzati per le colonne dalla sottosquadra complessa loj. Si noti che in assenza di SINISTRA, DESTRA o PIENA, si presume che un JOIN sia un join INNER; inoltre, se si specifica LEFT, RIGHT o FULL, l'OUTER è opzionale.

Un altro dettaglio da notare: il comportamento del join Informix OUTER vecchio stile in condizioni di filtro non è lo stesso del comportamento dei join OUTER SQL standard. Questo raramente fa la differenza, ma a volte potrebbe essere importante. Nel complesso, il comportamento dei join standard di SQL OUTER è più spesso quello che si desidera, ma se si eseguono test di regressione e si rileva una differenza nelle risposte, la spiegazione potrebbe essere che il join Informix OUTER vecchio stile funzioni diversamente dal nuovo stile SQL standard OUTER si unisce.