PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

raggruppando ogni N valori

Il primo approccio che viene in mente è usare row_number() per annotare la tabella, quindi raggruppare per blocchi di 16 righe.

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;

Nota che questo non includerà necessariamente 16 campioni per l'ultimo gruppo.

In alternativa puoi calcolare una media corrente utilizzando avg() come funzione della finestra:

SELECT id, avg(rainfall) OVER (ORDER BY id ROWS 15 PRECEDING)
FROM the_table;

... eventualmente annotandolo con il numero di riga e selezionando quelle desiderate:

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;

Questo ignorerà gli ultimi n<16 campioni, non restituendo una riga per loro.

Nota che suppongo che gli ID non siano garantiti per essere contigui. Se sono privi di gap, puoi semplicemente group by id/16 ed evitare la funzione finestra.