Si su caso es tan simple como sugieren los valores de ejemplo, respuesta de @Giorgos sirve muy bien.
Sin embargo, ese normalmente no es el caso . Si el id la columna es un serial , no puede confiar en la suposición de que una fila con una time anterior también tiene un id más pequeño .
También, time valores (o timestamp como probablemente lo haya hecho) pueden duplicarse fácilmente, debe hacer que el orden de clasificación no sea ambiguo.
Asumiendo que ambos pueden suceder, y desea el id desde la fila con la time más antigua por segmento de tiempo (en realidad, el más pequeño id por el tiempo más temprano , podría haber empates), esta consulta trataría la situación correctamente:
SELECT *
FROM (
SELECT DISTINCT ON (way, grp)
id, way, time AS time_from
, max(time) OVER (PARTITION BY way, grp) AS time_to
FROM (
SELECT *
, row_number() OVER (ORDER BY time, id) -- id as tie breaker
- row_number() OVER (PARTITION BY way ORDER BY time, id) AS grp
FROM table1
) t
ORDER BY way, grp, time, id
) sub
ORDER BY time_from, id;
-
ORDER BY time, idser inequívoco. Asumiendo que el tiempo no único, agregue el (supuesto único)idpara evitar resultados arbitrarios, que podrían cambiar entre consultas de manera furtiva. -
max(time) OVER (PARTITION BY way, grp):sinORDER BY, el marco de la ventana abarca todas las filas de la PARTICIÓN, por lo que obtenemos el máximo absoluto por intervalo de tiempo. -
La capa de consulta externa solo es necesaria para producir el orden de clasificación deseado en el resultado, ya que estamos vinculados a un
ORDER BYdiferente en la subconsultasubusandoDISTINCT ON. Detalles:
SQL Fiddle demostrando el caso de uso.
Si busca optimizar el rendimiento, una función plpgsql podría ser más rápida en tal caso. Respuesta estrechamente relacionada:
Aparte:no use el nombre de tipo básico time como identificador (también una palabra reservada en SQL estándar ).