Ich versuche, die folgende Abfrage auszuführen, um den Prozentsatz der Zeilen in meiner patients
Tabelle anzugeben, die einen Wert für die refinst
Spalte haben. Ich bekomme immer ein Ergebnis von 0.
select (count (refinst) / (select count(*) from patients) * 100) as "Formula"
from patients;
Die Tabelle enthält 15556 Zeilen. Davon select count(refinst) from patients
haben 1446 einen Wert in der refinst
Spalte. Die Antwort, die ich von der Abfrage erhalten möchte, wäre 30,62 ( 1446/15556*100=30.62XXXXX
auf zwei Dezimalstellen gerundet).
Ich bin mir ziemlich sicher, dass es etwas mit dem Datentyp der Zählergebnisse zu tun hat (Ganzzahlen nehme ich an). Wenn ich eine Ganzzahl durch eine Ganzzahl dividiere und das Ergebnis kleiner als 0 ist, wird es auf 0 abgeschnitten, richtig? Wenn dies der Fall ist, kann mir jemand zeigen, wie ich die Ergebnisse der Zählungen als Zahl mit 2 Dezimalstellen ausgeben kann, sodass das Ergebnis ebenfalls auf 2 Dezimalstellen gerundet wird?
Ich bin mir sicher, dass es einen besseren Weg gibt, diesen Code zu schreiben, als mehrere count-Anweisungen. Ich bin auf der Suche nach einer prozessoreffizienteren Methode, um diese Abfrage zu schreiben.
quelle
Antworten:
Verwenden Sie keine Unterauswahl. Beide Aggregate können aus derselben Abfrage abgeleitet werden. Billiger.
Dies gilt auch nicht für Fensterfunktionen, da Sie ein einzelnes Ergebnis und nicht ein Ergebnis pro Zeile berechnen möchten.
Umwandlung in einen beliebigen numerischen Typ , der Nachkommastellen unterstützt, wie @a_horse bereits erläutert .
Da du
round()
zwei Nachkommastellen haben willst schlage ich vornumeric
(das ist das gleiche wiedecimal
bei Postgres).Es reicht jedoch aus, einen an einer Berechnung beteiligten Wert zu setzen, vorzugsweise den ersten. Postgres stellt sich automatisch auf den Typ ein, bei dem keine Informationen verloren gehen.
Es ist im Allgemeinen eine gute Idee, vor der Teilung zu multiplizieren . Dies minimiert typischerweise Rundungsfehler und ist billiger.
In diesem Fall kann die erste Multiplikation (
count(refinst) * 100
) mit billiger und genauerinteger
Arithmetik berechnet werden . Erst dann werfen wir nachnumeric
und teilen durch die nächsteninteger
(die wir nicht zusätzlich werfen).Auf zwei Nachkommastellen gerundet:
quelle
Sie müssen jede Zahl, die an der Division beteiligt ist, in einen Typ umwandeln, der Dezimalstellen unterstützt:
Möglicherweise möchten Sie auch eine Fensterfunktion anstelle der skalaren Unterabfrage ausprobieren. Es könnte schneller sein:
quelle
Mir ist klar, dass dieser Thread ein paar Jahre alt ist, aber: versuchen Sie es mit 100.0 anstatt mit 100. Das sollte das Ergebnis automatisch als Float und nicht als Integer ausgeben.
quelle