count()を使用してパーセンテージを決定するPostgreSQL(キャストの問題)


19

次のクエリを実行してpatientsrefinst列の値を持つテーブル内の行の%を提供しようとしています。結果が0のままになります。

select (count (refinst) / (select count(*) from patients) * 100) as "Formula" 
from patients;

テーブルには15556行あり、そのうち1446行が列にselect count(refinst) from patients値を持っていることがわかりrefinstます。クエリから取得したい応答は30.62(1446/15556*100=30.62XXXXX小数点以下2桁に丸められます)になります。

カウント結果のデータ型(私が想定している整数)と関係があると確信しています。整数を整数で除算し、結果が0未満の場合、0に切り捨てられますか?その場合、カウントの結果を小数点以下2桁の数値としてキャストして、結果も小数点以下2桁に丸める方法を教えてもらえますか?

このコードを書くには、複数のcountステートメントよりも良い方法があると確信しています。特にこのクエリを書くための、よりプロセッサ効率の良い方法を探しています。


たぶん、この答えはあなたを助けることができます。
ジョンアンダーソンカルデナスディアス

回答:


26
SELECT (count(refinst) * 100)::numeric / count(*) AS refinst_percentage
FROM   patients;
  • 副選択を使用しないでください。両方の集計は、同じクエリから派生できます。安い。

  • また、行ごとに1つの結果ではなく、1つの結果を計算するため、ウィンドウ関数の場合はそうではありません。

  • すでに説明し@a_horseなど、小数桁をサポートする数値型にキャストします。 あなたは2桁の小数にしたいので(Postgresの場合と同じです)お勧めします。 ただし、計算に関係する1つの値(できれば最初の値)をキャストすれば十分です。Postgresは、情報を失わないタイプに自動的に対応します。
    round()numericdecimal

  • 通常、分割する乗算することをお勧めします。これは通常、丸め誤差を最小限に抑え、安価です。
    この場合、最初の乗算(count(refinst) * 100)は安価で正確なinteger算術で計算できます。のみその後、我々はにキャストnumeric隣で除算integer(私たちはどのませんさらにキャスト)。

小数2桁に丸められます。

SELECT round((count(refinst) * 100)::numeric / count(*), 2) AS refinst_percentage
FROM   patients;

もちろん、あなたは正しいです、ウィンドウ関数は必要ありません。ただし、実際には違いはありません(読みやすさは別として)。
a_horse_with_no_name 14年

3

除算に関係する各数値を、小数をサポートするタイプにキャストする必要があります。

select (count(refinst)::decimal / (select count(*) from patients)::decimal) * 100  as "Formula" 
from patients;

また、スカラーサブクエリの代わりにウィンドウ関数を試すこともできます。より速いかもしれません:

select (count(refinst)::decimal / (count(*) over ())::decimal) * 100 as "Formula" 
from patients;

0

私はこのスレッドが数年前のものであることに気付きましたが、100ではなく100.0で乗算してみてください。これにより、結果が整数ではなく浮動小数点として自動的にキャストされるはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.