Domanda

Lo so Oracle RDBMS non può unire una vista che ha un operatore di set in esso. Voglio sapere perché è così.

Per esempio, questo:

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

potrebbe essere trasformato in questo modo:

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
)

Queste due query sono equivalenti, giusto? [A cura]

È stato utile?

Soluzione

La trasformazione descrivi nella tua domanda modificato appare valida per me.

Ci sono molti molti molti diversi trasformazioni di query che l'ottimizzatore di Oracle potrebbe, in teoria, eseguire, ma in pratica questo è limitato a quelle trasformazioni che il team Oracle hanno effettivamente la briga di implementare .

Ogni trasformazione, se aggiunto, richiederebbe un investimento significativo nella codifica e test, e sarebbe fatto solo se è stata rilevata una domanda sufficiente nel mercato pagando.

Quindi, non è che essa "non può", necessariamente; semplicemente non lo fa, ancora.

Altri suggerimenti

Le query produrrà lo stesso gruppo di risultati, ma il piano di esecuzione è probabile che sia diverso. Mi aspetterei la prima query per essere più efficiente perché è confrontare contro tab_p una volta, contro i due volte nella seconda query.


In precedenza, entrambe le query utilizzate SELECT *, nessun alias di tabella in una di esse.

No, queste domande non sono equivalenti.

Il primo tornerà colonne sia dalla tabella derivata (dichiarazione UNION'd) e la tabella tab_p. La seconda query restituirà solo i valori della tabella derivata (com UNION'd), e nessun colonne dalla tabella tab_p. E 'più evidente se si sostituisce gli alias di tabella al posto di SELECT *:

Primo query:

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

seconda query:

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

Non ci sono colonne tab_p nella clausola SELECT della query interna, per la query esterna per fornire nel set di risultati finale.

Questa:

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 alla prima query. E 'con ANSI-92 uniscono la sintassi vs la sintassi ANSI-89 usato nella prima query.

Non sono equivalenti. La seconda query non riuscirà, come u non è definito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top