我有以下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。
怎么做?我尝试过限制和顶级,但没有成功
答案 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
这将在每个标准的单个索引扫描中计算AVG
和COUNT
。
在(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()部分,它会给你一个“几乎随机”的部分。