Não consigo mesclar uma união de todas as opiniões
-
26-09-2019 - |
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
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.