2012-02-26 6 views
0

'グループクォータ内で' using the bottom N個の値を計算します。私はいくつかの例を読んできました。hereは、この数値を計算するさまざまな方法を説明していますが、私はそれらを完全には理解していません(そしてPostgreSQL特有のものもありません)。私は私の質問を説明するために、以下の表を使用しています:サブグループ内集計計算を実行する

a | b | x 
    ---|---|------ 
    1 | 1 | 10.00 
    1 | 2 | 15.00 
    1 | 1 | 10.00 
    1 | 2 | 15.00 
    2 | 2 | 20.00 
    2 | 1 | 21.00 
    2 | 2 | 18.00 

SQLをテーブルを作成するには:

CREATE TABLE test(a int,b int,x decimal(6,2)); 
INSERT INTO test VALUES(1,1,10),(1,2,15), (1,1,10), (1,2,15), (2,2,20),(2,1,21),(2,2,18); 

私はグループごとに、最低N値の最小値を計算することができるようにしたいです。この例では、N = 2を送付しています。

SELECT 
    t1.a, 
    AVG(t1.x) as avg_x 
FROM 
    test AS t1 
GROUP BY t1.a 
ORDER BY avg_x 

返します:私が試してみました最初のステップは以下の通りである

a | avg_x 
--|------ 
1 | 12.50 
2 | 19.66 

私は(誤った結果が得られているが)サブクエリを作るために、そして制限することですやってみたことは何結果数:

SELECT foo.* FROM 
(SELECT 
    t1.a, 
    AVG(t1.x) as avg_x 
FROM 
    test AS t1 
GROUP BY t1.a 
ORDER BY avg_x 
) as foo 
ORDER BY foo.avg_x 
LIMIT 2 

私はそれは、サブグループごとLIMITを使用していないとして、これは、正しくありません知っています。私が返さするテーブルを明確にするためである:a=1ため

a | avg_x 
--|------ 
1 | 10.00 
2 | 19.00 

生の結果が値10.0, 10.0の平均で、x = 10.0, 10.0, 21です。

+2

私はちょっと混乱しました。最初のテーブルから、あなたが探している(テーブルとして)期待される結果は何ですか? –

+0

さらにもう1つ、主キーは何ですか? –

+0

明快さの欠如のため申し訳ありません - 私はこれを再度説明しようとしました。この例では、プライマリキーを使用していませんでした。 – djq

答えて

1

私は、これは、PostgreSQLで動作しますかなり確信している:

WITH T AS (
    SELECT A.*, ROW_NUMBER() OVER(PARTITION BY a ORDER BY x) AS rnk 
    FROM @yourTable AS A 
) 
SELECT a, AVG(x) avg_lowest_n_values 
FROM T 
WHERE rnk <= 2 
GROUP BY a; 
+0

が最初に 'b'、その後' a'が実行されます。それは理にかなっていますか?あなたの解決策は数​​値的に機能します(私は文法の頭の中で頭を覆そうとしています)。 – djq

+0

@celenius - あなたは 'b'と' a'でグループ化していますか? (a = 1、b = 1)、(a = 1、b = 2)、(a = 2、b = 1)、(a = 1、b = 1)の4つの結果レコードで終わることになります。 2、b = 2)。 –

+0

あなたは正しいです...私はこれを実現しています。私はちょうど 'a'でグループ化しています、' b'の値は実際には全く考慮されていません。私は私の質問を再編集します。 – djq

1
SELECT t1.a, round(AVG(t1.x), 2) as avg_x 
FROM (SELECT * 
    FROM test t2 
    WHERE x in (select x 
       from test t3 
       where t3.a = t2.a 
       order by x 
       limit 2)) as t1 
GROUP BY t1.a 
ORDER BY avg_x 

結果:私が正しくあなたの質問を理解している場合

a | avg_x 
--+------- 
1 | 10.00 
2 | 19.00 

関連する問題