2012-02-26 104 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 | avg_x 
--|------ 
1 | 10.00 
2 | 19.00 

的原始結果爲a=1x = 10.0, 10.0, 21,平均數值10.0, 10.0的。

+2

我有點困惑。從最初的表格中,您要查找的預期結果(作爲表格)是什麼? – 2012-02-26 23:58:38

+0

還有一件事,主要關鍵是什麼? – 2012-02-27 00:09:37

+0

抱歉,由於缺乏清晰度 - 我試圖再次重新解釋這一點。在這個例子中,我沒有使用主鍵。 – djq 2012-02-27 00:11:04

回答

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 2012-02-27 00:22:18

+0

@celenius - 你是由'b'然後'a'分組? (a = 1,b = 1),(a = 1,b = 2),(a = 2,b = 1),(a = 2,b = 2)。 – 2012-02-27 00:26:10

+0

你是對的....我只是意識到這一點。我只是用'a'分組,實際上並沒有考慮到'b'的值。我會重新編輯我的問題。 – djq 2012-02-27 00:29:53

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 

如果我理解正確你的問題。