0

Postgres をデータベースとして使用する RAILS アプリがあり、値の範囲でグラフを描画するユース ケースがあります。残念ながら、範囲は 10 進数であるため、Postgres の generate_series 関数を使用できません。これを10個の異なるクエリに分割するのではなく、これをクエリする最適な方法を見つけるのに助けが必要です. サンプルデータはこちら

  • スコア | の表があります。学生
  • クエリを指定すると、score-student タプルのセットが取得され、そこから range(min(score), max(score)) が取得されます。たとえば、範囲(10.25、16.80)
  • 上記の範囲を 0.655 の間隔で 10 ステップに分割する必要があります。これは (最大 - 最小)10 - 10.25,10.91,11.56,12.22,12.87 です。
  • 上記の各ステップについて、そのスコアと前の値の間の学生数を表示します
  • 結果は [(10.25,11232),(10.91,2434),....] の配列になります。

Postgres で単一のクエリまたは 10 以上のクエリでこれを行う方法/考えはありますか?

4

1 に答える 1

1

セットとしての結果(私にとってはより理にかなっています):

WITH base AS (
   SELECT student, score
   FROM   tbl
   WHERE  <some_condition>
   )
, border AS (
   SELECT min(score) AS min_score, max(score) AS max_score
   FROM   base
   )
SELECT lower_bound, ct
FROM  (
   SELECT step
        , min_score + ((max_score - min_score) * (step-1)) / 10 AS lower_bound
   FROM   border, generate_series(1,10) step
   ) x
LEFT   JOIN (
   SELECT width_bucket(b.score, x.min_score, x.max_score, 10) AS step
        , count(*)::int AS ct
   FROM   border x, base b
   GROUP  BY step
   ) y USING (step)
ORDER  BY step;

2 つのCTE (依然として有用) と、generate_series()見過ごされがちな関数width_bucket()を備えています。

質問で概説されているように、複合型の配列を生成するには、最初に一致する型を作成します(1回):

CREATE TYPE my_type AS (bound numeric, ct int);

numeric情報の欠如に対する値の仮定。次に、上記のクエリを配列コンストラクター
にフィードします。

SELECT ARRAY (
   <query from above>
   SELECT (lower_bound, ct::int)::my_type   -- only difference
   <query from above>
   );
于 2014-06-24T00:26:53.530 に答える