PostgreSQL:选择N导致逐个查询

时间:2010-01-02 11:09:23

标签: sql postgresql

我有以下SQL查询从我的表中选择一些结果:

select  avg(c3), count(c3), std  
from ssims where obraz = 'lena' group by std order by std

但是我为不同的std值执行了不同数量的测试,所以它给我这样的东西:

0.906176136363636;44;5
0.881669302325582;43;10
0.855873409090909;44;15
0.829195813953488;43;20
0.802071590909091;44;25
0.774523720930233;43;30
0.747213636363636;44;35
0.720115581395349;43;40
0.694712954545455;44;45
0.668683255813953;43;50

我想要做的是为每个std值选择常数(即20)个结果的平均值。所以在这样的查询之后,第二列对于每一行都是20。

怎么做?我尝试过限制和顶级,但没有成功

3 个答案:

答案 0 :(得分:6)

PostgreSQL 8.3

SELECT  a[1] AS avg_std, a[2] AS cnt_std, std
FROM    (
        SELECT  (
                SELECT  ARRAY[AVG(c3) , COUNT(*)]
                FROM    (
                        SELECT  c3
                        FROM    ssims si
                        WHERE   obraz = 'lena'
                                AND si.std = so.std
                        ORDER BY
                                id
                        LIMIT 20
                        ) q
                ) a
        FROM    (
                SELECT  DISTINCT std
                FROM    ssims
                WHERE   obraz = 'lena'
                ) so
        ) q

这将在每个标准的单个索引扫描中计算AVGCOUNT

(obraz, std, id)上创建一个复合索引,以便快速工作。

PostgreSQL 8.4

SELECT  AVG(c3), COUNT(*), std
FROM    (
        SELECT  std, c3, ROW_NUMBER() OVER (PARTITION BY std ORDER BY id) AS rn
        FROM    ssims
        WHERE   obraz = 'lena'
        ) q
WHERE   rn <= 20
GROUP BY
        std

答案 1 :(得分:0)

假设您的ssims表格中有一个我在我的示例中调用id的唯一ID列,您可以执行以下操作:

select avg(c3), count(c3), std from ssims where id in 
   (select id from ssims where obraz = 'lena' LIMIT 20)
   group by std order by std;

答案 2 :(得分:0)

如果您使用的是8.4,则应该可以使用窗口功能执行此操作。 (不确定std部分是什么,但我确定你可以添加回来)这样的东西(未经测试,所以你可能需要调整一些东西):

SELECT std,avg(c3), count(c3)
FROM (
 SELECT std, c3, row_number() OVER (
  PARTITION BY std ORDER BY random())
 ) foo
WHERE row_number <= 20
GROUP BY std
ORDER BY std

如果你不在乎你实际上得到一个随机子集,你可以删除ORDER BY random()部分,它会给你一个“几乎随机”的部分。