2009-06-10 4 views
2

auf Oracle 9i, warum produzieren folgende das Ergebnis 'abc'Warum erzwingt das Hinzufügen von count (*) zu einer Select-Anweisung eine Zeile in einer Unterabfrage?

select 'abc ' || (select txt from 
    (select 'xyz' as txt from dual where 1=2)) 
from dual 

während dieser 'abc xyz' erzeugt:

select 'abc ' || (select txt from 
    (select count(*), 'xyz' as txt from dual where 1=2)) 
from dual 

Warum funktioniert das Hinzufügen count (*) auf die Unterabfrage Ergebnis in anderes Verhalten? Sollte das Prädikat where 1=2 irgendwelche Ergebnisse in der Unterabfrage ausschließen?

Antwort

15
select count(*) from dual where 1=2 

gibt 0 zurück. Das ist eine Zeile mit dem Wert Null.

+0

Absolut richtig ... dieses Problem kam in einer viel komplexeren Abfrage, wo es durch anderes Verhalten verdeckt wurde. Ich erkannte schließlich den Fehler - der ursprüngliche Entwickler musste wirklich count (*) over() verwenden - die analytische Funktion gibt NULL korrekt zurück - was der Entwickler in diesem Fall wirklich wollte. – LBushkin

4

Es gibt die Anzahl von allem in der Unterabfrage zurück, die korrekt 0 ist. Die Verwendung von Aggregatfunktionen verhält sich immer (und korrekt) auf diese Weise und ist Teil des SQL-Standards.

0

count gibt immer einen numerischen Wert, 0 oder eine positive ganze Zahl zurück, so dass Sie immer eine Zeile in Ihrer Ergebnismenge haben.

Beachten Sie, dass die anderen Aggregatfunktionen NULL

0

Zu verstehen, wie Aggregatfunktionen arbeiten in SQL kritisch ist korrekt Abfragen zum Schreiben zurückkehren könnten. Wenn Sie einer Abfrage eine Aggregatfunktion (wie sum, avg, min, max, count) hinzufügen, bitten Sie die Datenbank, eine Gruppenoperation für eine Reihe von Ergebnissen durchzuführen. Die meisten Aggregate, wie min und max, geben null zurück, wenn sie mit einem leeren Satz von Zeilen zur Bearbeitung versehen sind. Die Ausnahme hiervon ist count() - it (korrekt) gibt 0 zurück, wenn eine leere Menge oder Zeilen angezeigt werden.

Diese Frage ergab sich aus der Analyse einer viel komplexeren Abfrage - eine mit mehreren Unterabfrageausdrücken in der SELECT-Klausel. Wie sich herausstellte, verursachte der Zusatz von count (*) im select-Ausdruck einige Schäden an den Ergebnissen - als es anfing, einen Wert zurückzuliefern, wo keiner erwartet wurde.

Was der Entwickler wirklich wollte, war ein Fall, in dem count(*) null produzieren würde. Der einfachste Weg, dies zu erreichen, ist der Einsatz von Analytics in Oracle. Die Abfrage kann geschrieben werden, um die analytische Zählung äquivalent zu verwenden: count(*) over()

select 'abc ' || (select txt from 
    (select count(*) over(), 'xyz' as txt from dual where 1=2)) 
from dual 
0
(select 'xyz' as txt from dual where 1=2)) 

Diese Unter Abfrage Keinerlei Zeilen zurück.

(select count(*), 'xyz' as txt from dual where 1=2)) 

Diese Unterabfrage gibt 1 Zeile die ganze Zeit zurück.

Das ist der Grund für das unterschiedliche Verhalten.

Verwandte Themen