как получить все непрерывные интервалы всех идентификаторов в отношении - PullRequest
0 голосов
/ 28 марта 2019

Итак, мое отношение простое: отношение (идентификатор, дата), идентификатор которого не является уникальным и не обязательно в любом порядке.Каждый идентификатор имеет дату (один и тот же идентификатор может иметь одинаковую дату).Моя проблема состоит в том, чтобы найти самый длинный интервал между датой и ее СЛЕДУЮЩЕЙ датой из всех идентификаторов.

Поэтому, если таблица выглядит следующим образом:

 ID     |   Date
--------+------------
    100 | 2015-06-20
    100 | 2015-01-21
    100 | 2016-04-23

ожидаемый результат будет

ID      |   interval
--------+------------
    100 | (2016-04-23 - 2015-06-20)

или если все даты идентификатора совпадают:

 ID     |   Date
--------+------------
    100 | 2016-04-23
    100 | 2016-04-23
    100 | 2016-04-23

ожидаемый результат должен быть

ID      |   interval
--------+------------
    100 |        0

это для одного идентификатора, в моем отношенииЕсть 100 идентификаторов вместе

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

Надеюсь, это то, что вы ищете

 WITH x AS 
(
   SELECT id, _date, lead_date, EXTRACT(epoch FROM age(lead_date,_date))/(3600*24) AS age
     FROM
        (
          SELECT *,  lead(_date) over(PARTITION BY id ORDER BY _date ) lead_date
            from table_log
            order by id, _date
        ) as z
    WHERE lead_date IS NOT NULL
    ORDER BY 4 DESC
 )
SELECT DISTINCT id ,
   (SELECT age FROM x WHERE x.id = t1.id ORDER BY age DESC LIMIT 1)
  FROM table_log t1

Здесь я использовал функцию Windows , чтобы получить следующую дату, чтобы определить продолжительность между 2 записями. с помощью Postgres Recursive запроса вы можете повторно использовать исходный запрос с функцией windows.

Я использовал DISTINCT из таблицы журнала, но вы также можете напрямую использовать таблицу, в которой храните идентификаторы.

0 голосов
/ 28 марта 2019

Думаю, этот запрос будет вам полезен:

select t.id,
       case
         when t.lower != t.upper then '(' || t.lower || ' - ' || t.upper || ')'
         else '0' end
from (select
             r.id,
             min(r.date) as lower,
             max(r.date) as upper
      from relation r
      group by r.id) t;

Мы используем подзапрос, чтобы найти нижнюю и верхнюю границы для каждого ID. После этого мы проверяем нижнюю и верхнюю границы, когда они равны, форматируемую строку, иначе ноль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...