Ако вашият случай е толкова прост, колкото показват примерните стойности, отговорът на @Giorgos служи добре.
Това обаче обикновено не е така . Ако id колоната е serial , не можете да разчитате на предположението, че ред с по-ранен time също има по-малък id .
Също така, time стойности (или timestamp както вероятно имате) могат лесно да бъдат дубликати, трябва да направите реда на сортиране недвусмислен.
Ако приемем, че и двете могат да се случат и искате id от реда с най-ранния time на отрязък от време (всъщност, най-малкият id за най-ранния време , може да има връзки), тази заявка ще се справи правилно със ситуацията:
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, idда бъде еднозначно. Ако приемем, че времето е не уникален, добавете (предполага се уникален)idза да избегнете произволни резултати - които могат да се променят между заявките по подъл начин. -
max(time) OVER (PARTITION BY way, grp):безORDER BY, рамката на прозореца обхваща всички редове на ДЯЛА, така че получаваме абсолютния максимум за отрязък от време. -
Външният слой на заявката е необходим само за създаване на желания ред на сортиране в резултата, тъй като сме обвързани с различен
ORDER BYв подзаявкатаsubчрез използване наDISTINCT ON. Подробности:
SQL Fiddle демонстриране на случая на употреба.
Ако искате да оптимизирате производителността, функцията plpgsql може да бъде по-бърза в такъв случай. Тясно свързан отговор:
Настрана:не използвайте основното име на тип time като идентификатор (също запазена дума в стандартния SQL ).