Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 执行子组内聚合计算_Sql_Postgresql_Grouping - Fatal编程技术网

Sql 执行子组内聚合计算

Sql 执行子组内聚合计算,sql,postgresql,grouping,Sql,Postgresql,Grouping,我想计算“组内报价”,计算底部的值。我已经通读了几个例子,这些例子解释了计算这个度量值的许多不同方法,但我并不完全理解它们,有些并不特定于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

我想计算“组内报价”,计算底部的值。我已经通读了几个例子,这些例子解释了计算这个度量值的许多不同方法,但我并不完全理解它们,有些并不特定于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
要创建表,请执行以下操作:

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
我知道这是不正确的,因为它没有使用每个分组的限制。要澄清我想要返回的表格是:

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

a=1的原始结果是x=10.0、10.0、21,平均值为10.0、10.0。

我确信这在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;
结果:


如果我没弄错你的问题。

我有点糊涂了。从最初的表中,您要查找的表的预期结果是什么?还有一件事,主键是什么?很抱歉不够清晰-我试图再次解释。在本例中,我没有使用主键。如何计算a=2的15.00?这是打字错误吗?不是应该是18+20/2=19.00吗?对不起,输入错误!我的错误。修复了它,感谢您优雅的解决方案。先是b,然后是a。这有意义吗?你的解决方案在数字上确实有效,我只是想了解一下语法。@celenius-你是按b分组,然后是a?这没有意义,你会得到4条结果记录,而不是两条:a=1,b=1,a=1,b=2,a=2,b=1,a=2,b=2。你是对的。。。。我才意识到这一点。我只是按a分组,实际上根本没有考虑b的值。我将重新编辑我的问题。
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