Pregunta

Sé Oracle RDBMS no puede fusionar una vista que tiene un operador de conjunto en ella. Quiero saber qué es eso.

Por ejemplo, esto:

SELECT u.*
FROM
 (
  SELECT a.a1    A,
        a.a2    B
   FROM tab_a a
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b
)     u,
tab_p p
WHERE p.a = u.a

podría ser transformado en esto:

SELECT *
FROM
 (
  SELECT a.a1    A,
         a.a2    B
    FROM tab_a a,
         tab_p p
   WHERE p.a = a.a1
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b,
         tab_p p
   WHERE p.a = b.b1
)

Estas dos consultas son equivalentes, ¿verdad? [Editado]

¿Fue útil?

Solución

La transformación que describes en tu pregunta editada parece válida para mí.

Hay muchos muchos muchos diferentes transformaciones de consulta que el optimizador de Oracle podría, en teoría, realizar, pero en la práctica se limita a esas transformaciones que el equipo de Oracle han realmente se molestó en poner en práctica .

Cada transformación, si se añaden, requeriría una inversión importante en la codificación y prueba, y sólo sería necesario si se ha detectado suficiente demanda en el mercado de pago.

Por lo tanto, no es que "no se puede", necesariamente; simplemente no lo hace, todavía.

Otros consejos

Las consultas se producen el mismo conjunto de resultados, pero el plan de ejecución es probable que sea diferente. Yo esperaría que la primera consulta sea más eficiente porque está comparando contra tab_p una vez, frente a los dos veces en la segunda consulta.


Anteriormente, ambas consultas utilizan SELECT *, sin alias de tabla en cualquiera de ellos.

No, esas consultas no son equivalentes.

El primer devolverá columnas tanto de la tabla derivada (declaración UNION'd) y la mesa tab_p. La segunda consulta sólo los valores de la tabla derivada (declaración UNION'd), y no hay columnas volver a la mesa tab_p. Es más evidente si se sustituye el alias de tabla en el lugar de SELECT *:

Primera consulta:

SELECT u.*, p.*
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u,
       tab_p p
 WHERE p.a = u.a

Segunda consulta:

SELECT x.*
 FROM (SELECT a.a1    A,
              a.a2    B
         FROM tab_a a,
              tab_p p
        WHERE p.a = a.a
       UNION ALL
       SELECT b.b1    A,
              b.b2    B
         FROM tab_b b,
              tab_p p
        WHERE p.a = b.a) x

No hay columnas tab_p en la cláusula SELECT de la consulta interna, para la consulta exterior para proporcionar en el conjunto de resultados final.

Este:

SELECT *
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u
  JOIN tab_p p ON p.a = u.a

.. es equivalente a la primera consulta. Se trata de utilizar ANSI-92 se unen a la sintaxis vs la sintaxis ANSI-89 usado en la primera consulta.

No son equivalentes. La segunda consulta fallará, como u no está definido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top