2011-08-25 9 views
6

Estoy tratando de convertir una consulta de Informix a Oracle:(combinaciones externas múltiples) unir tablas en Oracle

La consulta Informix se ve así:

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 consulta de Oracle se ve así:

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 

No estoy seguro de cómo unirme a las otras dos tablas.

¿Alguien me puede ayudar?

+0

¿Qué significa la sintaxis Informax? –

+0

¿Ha intentado [SQLINE] (http://www.sqlines.com/online)? –

Respuesta

0

Me gustaría probar la adición de estos:

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

Tablas tab7 y tab8 son interior-unidos entre sí; el resultado compuesto está unido externamente a las otras tablas. –

+0

'Y superior (atr.name)' podría eliminar la naturaleza exterior izquierdo de la combinación. – Ben

7

Creo que la consulta debe ser algo como esto:

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 

he cambiado el alias 'nd' sólo 'd' y 'ud' a 'v' para que todos los alias sean letras únicas. El OUTER(tab7 g, tab8 atr) anidado en la notación de Informix es en sí mismo una unión interna (como en la sub-selección en mi versión), pero ese conjunto de resultados está unido externamente con a.ac. Esto es lo que dice la reescritura.

Utilicé una cláusula WHERE en la subconsulta; la condición WHERE podría dejarse en la cláusula ON si lo prefiere. Lo más probable es que el optimizador maneje tanto de manera correcta como de manera equivalente. Del mismo modo, el AND u.id = 102 en la unión interna podría colocarse en una cláusula WHERE. Una vez más, el optimizador probablemente empujará la condición del filtro hacia abajo para un mejor rendimiento.

Tenga en cuenta que la función UPPER en la subconsulta probablemente requiera un escaneo de tabla, a menos que tenga un índice funcional en UPPER(atr.name).


Revisando esto, la transliteración de la parte inicial de la consulta no es precisa.

La consulta original incluía la cláusula FROM:

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

Las tablas tab3, tab4, tab5 y tab6 son de interior unidas entre sí, y el resultado es-exterior unido a tab1 y tab2. De manera similar, tab8 está unida internamente a tab7, pero el resultado de esto está unido externamente a la unión interna de las tablas 3-6. La respuesta original di (basado en la respuesta de esquema en la pregunta) estaría representado en la antigua notación Informix usando:

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

Por lo tanto, sería más exacto para transcribir la consulta original como:

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 

El problema residual sería garantizar que los alias correctos estén en uso para las columnas de la subconsulta compleja loj. Tenga en cuenta que en ausencia de IZQUIERDA, DERECHA o LLENA, se asume que una UNIÓN es una unión INTERIOR; también, si especifica LEFT, RIGHT o FULL, el OUTER es opcional.

Otro detalle a tener en cuenta: el comportamiento del viejo estilo Informix combinación externa en condiciones de filtro no es el mismo que el comportamiento del estándar SQL EXTERIOR une. Esto rara vez hace una diferencia, pero a veces puede ser importante. En general, el comportamiento del estándar SQL combinaciones externas es más por lo general lo que quiere, pero cuando se ejecutan pruebas de regresión y encuentra que hay una diferencia en las respuestas, la explicación podría ser que el viejo estilo de Informix combinación externa hace las cosas de manera diferente del nuevo estilo Standard SQL OUTER se une.

Cuestiones relacionadas