Pergunta

Eu sei que o Oracle RDMS não pode mesclar uma visualização que possui um operador definido. Eu quero saber por que isso.

Por exemplo, isso:

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

poderia ser transformado nisso:

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
)

Essas duas consultas são equivalentes, certo? [editado

Foi útil?

Solução

A transformação que você descreve em sua pergunta editada parece válida para mim.

Existem muitas transformações diferentes de consulta que o Oracle Optimizer poderia em teoria executar, mas na prática isso é limitado a essas transformações que a equipe Oracle tem realmente se preocupou em implementar.

Cada transformação, se adicionada, exigiria um investimento significativo em codificação e teste, e só seria feito se a demanda suficiente fosse detectada no mercado pagador.

Então, não é que "não pode", necessariamente; Simplesmente não, ainda.

Outras dicas

As consultas produzirão o mesmo conjunto de resultados, mas o plano de execução provavelmente será diferente. Eu esperaria que a primeira consulta fosse mais eficiente porque está comparando contra tab_p Uma vez, vs duas vezes na segunda consulta.


Anteriormente, ambas as consultas usadas selecionam *, nenhum alias de tabela em qualquer uma delas.

Não, essas consultas não são equivalentes.

A primeira retornará colunas da tabela derivada (declaração união) e do tab_p tabela. A segunda consulta retornará apenas valores da tabela derivada (declaração união), e nenhuma coluna do tab_p tabela. É mais óbvio se você substituir os aliases da tabela no lugar de SELECT *:

Primeira 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

Não há tab_p Colunas na cláusula selecionada da consulta interna, para que a consulta externa forneça no final do resultado.

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

.. é equivalente à primeira consulta. Ele está usando a sintaxe de junção ANSI-92 vs a sintaxe ANSI-89 usada na primeira consulta.

Eles não são equivalentes. A segunda consulta falhará, pois u não está definido.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top