2010-01-02 29 views
2

选择N组的结果我有以下的是选择从我的表中的一些结果。SQL查询:PostgreSQL的:通过查询

select avg(c3), count(c3), std 
from ssims where obraz = 'lena' group by std order by 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。

怎么办?我试图限制和顶部,但没有成功

+0

它应该使用的20行? – 2010-01-02 11:18:10

+0

它应该为每个std值选择20行(无论哪个) – Gacek 2010-01-02 11:31:12

+0

如果您只是在查看一个随机子集并进行平均,那么为什么您要做20行或更多行会影响它?我可以看到如何做很少的行会给你一个不正确的数字,但太多​​? – 2010-01-02 12:03:41

回答

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 

这将在一个单一的索引扫描每个STD计数两者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 
+0

8.4版本作为一个魅力工程很漂亮!谢谢! – Gacek 2010-01-03 15:42:28

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; 
+0

是的,它有这样的专栏,但是这不起作用。出现错误是因为std必须在子查询中同时选中。 错误消息: 错误:列“ssims.id”必须出现在GROUP BY子句中或在聚合函数中使用 – Gacek 2010-01-02 13:08:52

+0

您可以从内部选择中删除group by语句并应用到外部选择,因为我现在已完成。根据您需要的结果,您也可以在内部选择中将id添加到group by语句中。 – 2010-01-02 13:25:26

+0

nope,它将只选择20个元素,而不是每个std值20个元素 – Gacek 2010-01-02 13:31:29

0

如果你在8.4,你应该可以用窗口函数来做到这一点。 (不知道什么是性病的部分是,但我敢肯定,你可以添加回)像这样(未经测试,所以你可能需要调整一些东西):

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()部分,它会给你一个“几乎是随机的”。

+0

它仍然返回一个错误(无标准列),即使在8.4 – Gacek 2010-01-03 15:43:18

+0

呃,我现在看到查询缺少一个“FROM ssims”。它需要在“)foo”部分之前。这就是我的意思,“你可能需要调整一些东西” – 2010-01-03 21:39:37