Estou tentando executar a seguinte consulta para fornecer a% de linhas na minha patients
tabela que possuem um valor na refinst
coluna. Eu continuo recebendo um resultado de 0.
select (count (refinst) / (select count(*) from patients) * 100) as "Formula"
from patients;
A tabela possui 15556 linhas e select count(refinst) from patients
informa que 1446 delas possuem um valor na refinst
coluna. A resposta que gostaria de obter da consulta seria 30,62 ( 1446/15556*100=30.62XXXXX
, arredondada para duas casas decimais).
Tenho certeza de que tem algo a ver com o tipo de dados dos resultados da contagem (números inteiros, estou assumindo). Se eu dividir um número inteiro por um número inteiro e o resultado for menor que 0, ele será truncado para 0 correto? Se for esse o caso, alguém pode me mostrar como converter os resultados das contagens como um número com 2 casas decimais, para que o resultado também seja arredondado para 2 casas decimais?
Tenho certeza de que há uma maneira melhor de escrever esse código do que várias instruções de contagem. Estou procurando uma maneira mais eficiente do processador para escrever essa consulta em particular.
fonte
Respostas:
Você não usar um subselect. Ambos os agregados podem ser derivados da mesma consulta. Mais barato.
Além disso, esse não é o caso das funções da janela, pois você deseja calcular um único resultado e não um resultado por linha.
Transmitir para qualquer tipo numérico que suporte dígitos fracionários, como @a_horse já explicado .
Como você deseja
round()
dois dígitos fracionários, sugironumeric
(que é o mesmo quedecimal
no Postgres).Mas basta lançar um valor envolvido em um cálculo, de preferência o primeiro. O Postgres aceita automaticamente o tipo que não perde informações.
Geralmente, é uma boa ideia multiplicar antes de dividir . Isso geralmente minimiza os erros de arredondamento e é mais barato.
Nesse caso, a primeira multiplicação (
count(refinst) * 100
) pode ser calculada cominteger
aritmética barata e exata . Só então nós escalado paranumeric
e dividir pelo ladointeger
(que nós não lançar adicionalmente).Arredondado para dois dígitos fracionários:
fonte
Você precisa converter cada número envolvido na divisão em um tipo que suporte decimais:
Você também pode tentar uma função de janela em vez da subconsulta escalar. Pode ser mais rápido:
fonte
Sei que esse segmento tem alguns anos, mas: tente multiplicar por 100,0 em vez de 100 Isso deve converter automaticamente o resultado como um float em vez de um número inteiro.
fonte