Frage

ich weiß, Oracle RDMS kann nicht eine Ansicht zusammenführen, die einen Satz Operator in ihm hat. Ich will wissen, warum das so ist.

Zum Beispiel dieses:

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

könnte in diese umgewandelt werden:

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
)

Diese beiden Abfragen gleichwertig, nicht wahr? [Editiert]

War es hilfreich?

Lösung

Die Transformation Sie in Ihrer editierten Frage beschreiben scheint gültig zu mir.

Es gibt viele viele viele verschiedene Abfrage-Transformationen, dass die Oracle-Optimierer in der Theorie könnte durchführen, aber in der Praxis wird dies auf diese Transformationen beschränkt, dass das Oracle-Team, wirklich .

Jede Transformation, wenn hinzugefügt, würde erhebliche Investitionen erfordern bei der Codierung und Testen, und würde nur dann erfolgen, wenn eine ausreichende Nachfrage in der Zahl Markt erkannt wurde.

Also, es ist nicht, dass es „nicht“, unbedingt; es funktioniert einfach nicht, noch nicht.

Andere Tipps

Die Abfragen werden die gleiche resultset produzieren, aber der Ausführungsplan wird wahrscheinlich anders sein. Ich würde die erste Abfrage erwartet effizienter zu sein, weil es gegen tab_p vergleicht einmal, gegen das zwei Mal in der zweiten Abfrage.


Zuvor

, verwendet beide Abfragen SELECT *, keine Tabellen-Alias ??in einer von ihnen.

Nein, sind diese Abfragen nicht gleichwertig sind.

Die erste wird Spalt zurückgeben sowohl aus der abgeleiteten Tabelle (UNION'd Anweisung) und die tab_p Tabelle. Die zweite Abfrage wird nur Rückgabewerte aus der abgeleiteten Tabelle (UNION'd-Anweisung), und keine Spalten aus der tab_p Tabelle. Es ist offensichtlicher, wenn Sie die Tabelle Aliase an der Stelle SELECT * ersetzen:

Erste Abfrage:

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

Zweite Abfrage:

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

Es gibt keine tab_p Spalten in der SELECT-Klausel der inneren Abfrage, für die äußere Abfrage in das ultimative resultset zu bieten.

Dieses:

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

.. entspricht die erste Abfrage. Es wird unter Verwendung von ANSI-92-Join-Syntax gegen die ANSI-89-Syntax in der ersten Abfrage verwendet wird.

Sie sind nicht gleichwertig. Die zweite Abfrage wird fehlschlagen, da u nicht definiert ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top