0

我們有一個使用Postgres作爲數據庫的RAILS應用程序,並有一個用於在一系列值上繪製圖形的用例。不幸的是,範圍是十進制的,所以我不能使用Postgres的generate_series函數。需要幫助確定查詢的最佳方式,而不是將其分解爲10個不同的查詢。以下是樣本數據Postgres查詢一個範圍內的10個步驟

  • 我們有一張表,評分|學生
  • 給出一個查詢,我會得到一組得分學生元組,從中我可以得到範圍(min(分數),max(分數))。例如範圍(10.25,16.80)
  • 我們需要打破上述範圍分成10個步驟與0.655的間隔,它是(最大值 - 最小值)10 - 10.25,10.91,11.56,12.22,12.87
  • 對於每個步驟以上表明,得分和先前值之間的學生數量
  • 結果將與[(10.25,11232),(10.91,2434),....]

任何方式/想法到陣列在Postgres中,在單個查詢中執行此操作還是少於10次查詢?

+1

也許你應該儘量去適應這一點:http://stackoverflow.com/questions/232387/in-sql-how-can-you-group-by-範圍內 –

+0

不錯,感謝指針@RubyRacer – sumit

+0

這個問題應該提供一個表定義,您的Postgres版本,一些示例值和您嘗試的查詢(即使它不工作)。理想情況下,一個SQL小提琴([隨機示例](http://sqlfiddle.com/#!15/bc7d7/3))。 –

回答

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; 

它擁有兩個CTEsgenerate_series()(仍然有用),並經常被忽略的功能width_bucket()

爲了產生一種陣列複合類型,像在問題中概述的,首先創建一個匹配型(一次):

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

假設因缺乏信息numeric值。
再喂上面的查詢到array constructor

SELECT ARRAY (
    <query from above> 
    SELECT (lower_bound, ct::int)::my_type -- only difference 
    <query from above> 
    ); 
+1

@ erwin-brandsetter,感謝您提供缺少postgres版本和sqlfiddle的詳細解答和道歉(不知道)。我在9.3上,所以可以訪問你提到的功能。 width_bucket()似乎是我用例的正確工具。隨着你的答案,我能夠得到我想要的。我也遇到http://tapoueh.org/blog/2014/02/21-PostgreSQL-histogram,這有助於更多。 – sumit

相關問題