执行子组内聚合计算

时间:2012-02-26 23:50:32

标签: sql postgresql grouping

我想计算'组内配额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=1的原始结果为x = 10.0, 10.0, 21,平均值为10.0, 10.0

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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

如果我理解你的问题。