Möglicher Oracle-Fehler mit Unterabfragen und Gruppenfunktionen

8

kann mir jemand erklären, warum die folgende Abfrage zwei Zeilen zurückgibt und nicht nur eine?

%Vor%

Stimmt es, dass Oracle zwei Zeilen liefert? Meiner Meinung nach sollte die Zeile mit c1 = ASDF nicht im Ergebnis sein.

Hier ist ein Screenshot des Ergebnisses der ersten Abfrage:

Ich habe es in den folgenden Versionen getestet, immer mit dem gleichen Ergebnis:

  • Oracle-Datenbank 11g Enterprise Edition Version 11.2.0.3.0 - 64-Bit-Produktion
  • Oracle-Datenbank 12c Enterprise Edition Version 12.1.0.2.0 - 64-Bit-Produktion
bernhard.weingartner 11.11.2016, 11:04
quelle

3 Antworten

3

Nein, das ist kein Fehler . Aggregatfunktionen sind der Grund, warum Sie dieses unerwartete Ergebnis sehen. So funktioniert es. SUM() function sowie MAX() function geben NULL (1 Zeile) zurück, wenn von der Abfrage keine Zeilen zurückgegeben werden. Wenn Ihre Abfrage ausgeführt wird, wendet optimizer predicate pushing transformation an und Ihre ursprüngliche Abfrage wird (wird nicht die gesamte Ablaufverfolgung, nur transformierte Abfrage):

%Vor%

[1] Wegen des Prädikats gibt das Drücken Ihrer Faust-Unterabfrage keine Zeilen zurück und wenn eine Aggregatfunktion (außer count und einige andere), MAX oder SUM oder sogar beide, wie in diesem Fall leer verwendet Ergebnismenge NULL wird zurückgegeben - 1 Zeile + 1 Zeile wird von der zweiten Unterabfrage zurückgegeben und ergibt somit 2 Zeilen Ergebnismenge, die Sie betrachten.

Hier ist eine einfache Demonstration:

%Vor%     
Nick Krasnov 11.11.2016 12:36
quelle
1

Es sieht definitiv wie ein Fehler aus.

Ich weiß nicht wirklich, wie man Pläne erklärt, aber hier ist es. Es scheint mir, das Prädikat wurde nur an einen der UNION-Mitglieder weitergegeben und es wurde in "NULL IST NICHT NULL" umgewandelt, was total komisch ist.

Beachten Sie, dass die Zeichenfolgen in "a" und "b" geändert werden können (so dass wir keine Sonderzeichen verwenden), UNION und UNION ALL erzeugen denselben Fehler, und der Fehler scheint durch den MAX (SUM (1)) im ersten Zweig; Einfach das durch NULL oder irgendetwas anderes zu ersetzen, das "einfach" ist, oder sogar mit SUM (1) (ohne das MAX) verursacht, dass die Abfrage richtig arbeitet.

HINZUGEFÜGT : Seltsamerweise, wenn ich MAX(SUM(1)) entweder in MAX(1) oder SUM(1) ändere oder wenn ich einfach in die Literalnummer 1 ändere, funktioniert die Abfrage korrekt - aber Der Explain-Plan zeigt immer noch das gleiche seltsame Prädikat "NULL IST NICHT NULL". Das Problem ist also, dass das Prädikat nicht auf beide Zweige der Vereinigung übertragen wird, nicht auf die Prädikatumwandlung. (Und selbst das erklärt nicht, warum c2 in der zusätzlichen Zeile in der Ergebnismenge als NULL erscheint.) MEHR HINZUGEFÜGT (siehe Kommentare unten) - wie sich herausstellt, ist das Prädikat IS in beide Zweige der UNION geschoben, und genau das verursacht das Problem (wie Nicholas in seiner Antwort erklärt).

%Vor%     
mathguy 11.11.2016 11:26
quelle
0

Ein viel einfacheres Beispiel führt zu demselben Fehler:

%Vor%

Ich muss gestehen, dass ich total verwirrt bin. Warum löscht der Filter den Datensatz nicht, wodurch Ergebnissätze eliminiert werden?

    
Brian Leach 11.11.2016 20:03
quelle

Tags und Links