我有这样PostgreSQL中的表。 我想执行类似平均和最大聚合函数基于ID的所有16条(这是主键)。 比如我要计算前16条记录和第二条记录等等平均值。
+-----+-------------
| ID | rainfall |
+-----+----------- |
| 1 | 110.2 |
| 2 | 56.6 |
| 3 | 65.6 |
| 4 | 75.9 |
+-----+------------
我有这样PostgreSQL中的表。 我想执行类似平均和最大聚合函数基于ID的所有16条(这是主键)。 比如我要计算前16条记录和第二条记录等等平均值。
+-----+-------------
| ID | rainfall |
+-----+----------- |
| 1 | 110.2 |
| 2 | 56.6 |
| 3 | 65.6 |
| 4 | 75.9 |
+-----+------------
即想到的第一方法是使用row_number()
由16行的块来注释表,那么基团。
SELECT min(id) as first_id, max(id) AS last_id, avg(rainfall) AS avg_this_16
FROM (
SELECT id, rainfall, row_number() OVER (order by id) AS n
FROM the_table
) x(id,rainfall,n)
GROUP BY n/16
ORDER BY n/16;
请注意,这并不一定会包含16个样本的最后一组。
或者您可以通过使用计算运行平均值 avg()
作为窗口函数:
SELECT id, avg(rainfall) OVER (ORDER BY id ROWS 15 PRECEDING)
FROM the_table;
......可能是注释与行号,并选择您喜欢的类型:
SELECT id AS greatest_id_in_group, avg_last_16_inclusive FROM (
SELECT
id,
avg(rainfall) OVER (ORDER BY id ROWS 15 PRECEDING) AS avg_last_16_inclusive,
row_number() OVER (ORDER BY id) AS n
FROM the_table
) x WHERE n % 16 = 0;
这将忽略最后n <16个样本,而不是为他们返回行。
请注意,我假设的ID不能保证是连续的。 如果它们是间隙少,你可以group by id/16
,避免窗函数。
迟到的回答,但无论如何,以供参考
自ID
被说成是连续的和间隙更小,那么这将导致非常简单的
SELECT avg(rainfall),string_agg(id::text, ',')
FROM the_table
GROUP BY (id - 1) / 16;
注意到(id - 1)
以获得从零到15的分组,否则第一组可以去相位
PS:@Craig林格给他的回答最后一个提示,但没有贴是代码
请注意,我假设的ID不能保证是连续的。 如果它们是间隙少,你可以通过组ID / 16,避免窗函数。