простирается от упорядоченных дат с помощью PostgreSQL

#sql #postgresql

#sql #postgresql

Вопрос:

У меня есть таблица, подобная

 group | date
a     | 2002-01-03
a     | 2002-01-17
a     | 2002-03-18
b     | 2001-01-02
  

Я бы хотел превратить это в серию интервалов, таких как

 group | start      | stop
a     | 2002-01-03 | 2002-01-17
a     | 2002-01-17 | 2002-03-18
a     | 2002-03-18 |
b     | 2001-01-02 | 
  

Я мог бы сделать это с

 select distinct on (left.group, left.date) 
    left.group as group,
    left.date as start,
    right.date as stop
from dates as left
left join dates as right
on left.group = right.group
    and left.date < right.date
order by group, left.date, right.date
  

но есть ли лучший способ сделать это (большое объединение и сортировка в реальной таблице выполняются медленно)

Ответ №1:

Используйте lead() :

 select d.*, lead(d.date) over (partition by d.group order by date)
from dates d
order by group, start;
  

Комментарии:

1. должно ли это быть «выбрать d.*, перейти (d.date) поверх (разделение по d.групповому порядку по дате) из дат, упорядоченных по d.date», или этот внешний «порядок по» не нужен?

2. @fgregg Внешний «порядок по» не нужен, поскольку он обрабатывается в OVER() предложении. Оконные функции запускаются после реализации набора данных.

3. @fgregg . , , Если вы хотите получить результаты в определенном порядке, то вы всегда должны включать an order by в самый внешний запрос. Игнорируйте то, что прокомментировал JSpratt. Это просто неправильно.