Próbuję uruchomić następujące zapytanie, aby podać% wierszy w mojej patients
tabeli, które mają wartość refinst
kolumny. Ciągle otrzymuję wynik 0.
select (count (refinst) / (select count(*) from patients) * 100) as "Formula"
from patients;
Tabela ma 15556 wierszy i select count(refinst) from patients
mówi mi, że 1446 z nich ma wartość w refinst
kolumnie. Odpowiedź, którą chciałbym uzyskać z zapytania, wynosiłaby 30,62 ( 1446/15556*100=30.62XXXXX
w zaokrągleniu do dwóch miejsc po przecinku).
Jestem pewien, że ma to coś wspólnego z typem danych wyników zliczania (zakładam, że liczby całkowite). Jeśli podzielę liczbę całkowitą przez liczbę całkowitą, a wynik jest mniejszy niż 0, to zostanie obcięty do 0, prawda? Jeśli tak jest, czy ktoś może mi pokazać, jak rzutować wyniki liczenia jako liczbę z 2 miejscami po przecinku, aby wynik również został zaokrąglony do 2 miejsc po przecinku?
Jestem pewien, że istnieje lepszy sposób na napisanie tego kodu niż wiele instrukcji zliczania. Szukam w szczególności bardziej wydajnego sposobu na napisanie tego zapytania.
źródło
Odpowiedzi:
Czy nie używać podselekcji. Oba agregaty można wyprowadzić z tego samego zapytania. Taniej.
Ponadto, jest to nie sprawa dla funkcji okna, ponieważ chcesz obliczyć pojedynczy wynik, a nie jeden wynik w każdym wierszu.
Przesyłaj na dowolny typ liczbowy, który obsługuje cyfry ułamkowe, jak już wyjaśniono @a_horse .
Ponieważ chcesz
round()
użyć dwóch cyfr ułamkowych, sugerujęnumeric
(to samo codecimal
w Postgresie).Ale wystarczy rzucić jedną wartość uwzględnioną w obliczeniach, najlepiej pierwszą. Postgres automatycznie ustala typ, który nie powoduje utraty informacji.
Na ogół dobrym pomysłem jest pomnożenie przed podzieleniem . Zwykle minimalizuje to błędy zaokrąglania i jest tańsze.
W takim przypadku pierwsze mnożenie (
count(refinst) * 100
) można obliczyć za pomocą taniej i dokładnejinteger
arytmetyki. Dopiero wtedy rzucamynumeric
i dzielimy przez kolejnychinteger
(których nie rzucamy dodatkowo).Zaokrąglone do dwóch cyfr ułamkowych:
źródło
Musisz rzucić każdą liczbę uczestniczącą w podziale na typ, który obsługuje liczby dziesiętne:
Możesz także wypróbować funkcję okna zamiast podskalarnego zapytania. Może być szybciej:
źródło
Zdaję sobie sprawę, że ten wątek ma kilka lat, ale: spróbuj pomnożyć przez 100,0 zamiast przez 100, co powinno automatycznie rzutować wynik jako liczbę zmiennoprzecinkową, a nie liczbę całkowitą.
źródło