2013-07-16 9 views
25

Ich möchte Division in einer SELECT-Klausel durchführen. Wenn ich einige Tabellen anschließe und die Aggregatfunktion verwende, habe ich oft Null- oder Nullwerte als Teiler. Ich komme nur auf diese Methode zur Vermeidung der Division durch Null- und Nullwerte.Vermeiden Sie die Division durch Null in PostgreSQL

(CASE(COALESCE(COUNT(column_name),1)) WHEN 0 THEN 1 
ELSE (COALESCE(COUNT(column_name),1)) END) 

Ich frage mich, ob es eine bessere Möglichkeit gibt, dies zu tun?

+4

Division durch einen Nullwert ist kein Problem in der Art, wie Division durch Null ist. Übrigens gibt count() nie null zurück. –

+0

Das wusste ich nicht! Danke für die Information. – William

Antwort

24

Da count() niezurück (im Gegensatz zu anderen Aggregatfunktionen), haben Sie nur die 0 Fall zu fangen (das ist der einzige Problemfall ist sowieso):

CASE count(column_name) 
    WHEN 0 THEN 1 
    ELSE count(column_name) 
END 

Quoting the manual about aggregate functions:

Es sei darauf hingewiesen, dass mit Ausnahme von count werden soll, Diese Funktionen geben einen Nullwert zurück, wenn keine Zeilen ausgewählt sind.

+0

danke für den Link, ich war mir dessen nicht bewusst +1 :) – Akash

92

Sie können die NULLIF-Funktion z.

something/NULLIF(column_name,0) 

Wenn der Wert von column_name 0 - Ergebnis des gesamten Ausdrucks wird NULL sein

+7

etwas wie value/COALESCE (NULLIF (column_name, 0), 1) würde funktionieren Ich nehme an – Akash

+0

Versuchte es mit COALESCE als @Akash vorgeschlagen und es tat die Arbeit –

+1

NULLIF funktioniert genau wie Yuiry vorgeschlagen - danke! –

1

Wenn Sie wollen, dass der Teiler 1 zu sein, wenn die Zählung Null:

count(column_name) + 1 * (count(column_name) = 0)::integer 

Die Besetzung von true zu integer ist 1.

+0

Netter Trick, aber ich denke, dass eine Fallaussage offensichtlicher sein könnte. –

+0

'CASE' ist auch schneller, wenn auch ausführlicher. –

12

Ich weiß, das eine alte Frage, aber eine andere Lösung wäre die Verwendung der größten Funktion zu machen:

greatest(count(column_name), 1) -- NULL and 0 are valid argument values 

Hinweis: Meine Präferenz sein würde Entweder gebe NULL zurück, wie in Erwins und Yuriys Antwort, oder um dies logisch zu lösen, indem der Wert 0 vor der Division ermittelt wird undzurückgegeben wird. Andernfalls können die Daten falsch dargestellt werden, indem 1 verwendet wird.

+0

Ich werde das verwenden, da mein Divisor ist eine "verstrichene Zeit" für einen Prozess, und 0 bedeutet wahrscheinlich einen Bruchteil einer Sekunde, so Ich verwende 0,01 Minuten als Standardzeit. Ich vergleiche nur die Prozessleistung. – PhilHibbs

Verwandte Themen