J'essaie d'exécuter la requête suivante pour fournir le% de lignes de ma patients
table qui ont une valeur dans la refinst
colonne. J'obtiens toujours un résultat de 0.
select (count (refinst) / (select count(*) from patients) * 100) as "Formula"
from patients;
Le tableau comporte 15556 lignes et select count(refinst) from patients
m'indique que 1446 d'entre elles ont une valeur dans la refinst
colonne. La réponse que j'aimerais obtenir de la requête serait 30,62 ( 1446/15556*100=30.62XXXXX
, arrondie à deux décimales).
Je suis presque sûr que cela a quelque chose à voir avec le type de données des résultats de comptage (entiers, je suppose). Si je divise un entier par un entier et que le résultat est inférieur à 0, il est tronqué à 0 correct? Si tel est le cas, quelqu'un peut-il me montrer comment convertir les résultats des décomptes en nombre avec 2 décimales afin que le résultat soit également arrondi à 2 décimales?
Je suis sûr qu'il existe une meilleure façon d'écrire ce code que plusieurs instructions de comptage. Je recherche un moyen plus efficace pour écrire cette requête en particulier.
la source
Réponses:
N'utilisez pas de sous -sélection. Les deux agrégats peuvent être dérivés de la même requête. Moins cher.
En outre, ce n'est pas le cas pour les fonctions de fenêtre, car vous souhaitez calculer un seul résultat, et non un résultat par ligne.
Cast à n'importe quel type numérique qui prend en charge les chiffres fractionnaires, comme @a_horse déjà expliqué .
Étant donné que vous voulez
round()
deux chiffres fractionnaires, je suggèrenumeric
(ce qui est le même quedecimal
dans Postgres).Mais il suffit de lancer une valeur impliquée dans un calcul, de préférence la première. Postgres se contente automatiquement du type qui ne perd pas d'informations.
C'est généralement une bonne idée de multiplier avant de diviser . Cela minimise généralement les erreurs d'arrondi et est moins cher.
Dans ce cas, la première multiplication (
count(refinst) * 100
) peut être calculée avec uneinteger
arithmétique exacte et bon marché . Ce n'est qu'alors que nous lançonsnumeric
et divisons par le suivantinteger
(que nous ne lançons pas en plus).Arrondi à deux chiffres fractionnaires:
la source
Vous devez convertir chaque nombre impliqué dans la division en un type prenant en charge les décimales:
Vous pouvez également essayer une fonction de fenêtre au lieu de la sous-requête scalaire. Cela pourrait être plus rapide:
la source
Je me rends compte que ce fil a quelques années mais: essayez de multiplier par 100,0 plutôt que par 100 Cela devrait automatiquement convertir le résultat en un flottant plutôt qu'en un entier.
la source