Mi mesa se ve así
id | job_id | measurement_id | value | timestamp --------+----------+------------------+------------------+----------- 1 | myJobId | myMeasurementId | 55.6111297607422 | 49212 2 | myJobId | myMeasurementId | 55.6607780456543 | 49412
Me gustaría obtener el valor máximo en ciertos intervalos de tiempo, sin embargo, también necesito la marca de tiempo asociada con la medición individual.
range | max | timestamp ----------+---------------------+------------------ 0 | 68.7833782357044665 | 20535552 377613 | 67.9283221509389440 | 20535552 755226 | 67.2932168855194184 | 20535552
Intenté la siguiente declaración pero me encontré con un error
select (timestamp/377613)*377613 as range, max(value), timestamp from measurements where job_id = 'myJobId' and measurement_id = 'myMeasurementId' group by timestamp/377613 order by 1; ERROR: column "measurements.timestamp" must appear in the GROUP BY clause or be used in an aggregate function
Sin la segunda marca de tiempo, la declaración funciona bien, pero, por supuesto, no entrega la marca de tiempo asociada con el valor máximo. ¿Cómo puedo obtener ese valor?
Puedes usar row_number()
select * from ( select (timestamp/377613)*377613 as range, value, timestamp, row_number() over(partition by (timestamp/377613)*377613 order by value desc) as rn from measurements where job_id = 'myJobId' and measurement_id = 'myMeasurementId' )A when rn=1
En Postgres, debe usar distinct on
para esta operación. Para mayor comodidad, también puede calcular el rango utilizando una unión lateral:
select distinct on (v.range) v.range, m.value), m.timestamp from measurements m cross join lateral (values (m.timestamp/377613) * 377613)) as range where m.job_id = 'myJobId' and m.measurement_id = 'myMeasurementId' order by v.range, m.timestamp;
distinct on
es una extensión de Postgres, pero resulta ser bastante útil. Ordena los datos y elige la primera fila que encuentra para cada valor en la cláusula distinct on
.
En general, distinct on
es más rápido que la consulta correspondiente usando funciones de ventana.