Использование даты из следующей строки в качестве даты окончания текущей строки - PullRequest
0 голосов
/ 23 сентября 2019

У меня есть таблица, которая выглядит следующим образом:

ID | FOCUS      | DATE
----------------------------
 1 | equipment  | 2018-01-01
 2 | uniform    | 2018-02-14
 3 | attendance | 2018-04-03

Строки добавляются по мере появления новых фокусов.

Я хочу получить дату начала и дату окончаниядля конкретного фокуса, предполагая, что он заканчивается, как начинается следующий.Создание представления, такого как:

ID | FOCUS      | STARTDATE  | ENDDATE
--------------------------------------
 1 | equipment  | 2018-01-01 | 2018-02-14
 2 | uniform    | 2018-02-14 | 2018-04-03
 3 | attendance | 2018-04-03 | NULL

Используемая мной база данных не имеет функций LEAD или LAG, поэтому мне нужен способ сделать это на чистом SQL.Все решения, которые я нашел, используют LEAD и LAG.Есть идеи?

Ответы [ 4 ]

3 голосов
/ 23 сентября 2019

Вы можете получить желаемый результат, LEFT JOIN предоставив таблицу самой себе, при этом дата в правой таблице является минимальным значением даты, превышающим дату в левой таблице.Этот запрос будет работать независимо от ID последовательных значений:

SELECT t1.ID, t1.FOCUS, t1.DATE AS STARTDATE, t2.DATE AS ENDDATE
FROM table1 t1
LEFT JOIN table1 t2 ON t2.DATE = (SELECT MIN(DATE)
                                  FROM table1 t3
                                  WHERE t3.DATE > t1.DATE)

Вывод:

ID  FOCUS       STARTDATE   ENDDATE
1   equipment   2018-01-01  2018-02-14
2   uniform     2018-02-14  2018-04-03
3   attendance  2018-04-03  null

Демонстрация на dbfiddle

Если этовозможно, что два события могут завершиться в один и тот же день, вы можете изменить запрос следующим образом, который будет работать до тех пор, пока значения ID увеличиваются при увеличении значений DATE.

SELECT DISTINCT t1.ID, t1.FOCUS, t1.DATE AS STARTDATE, t2.DATE AS ENDDATE
FROM table1 t1
LEFT JOIN table1 t2 ON t2.DATE = (SELECT MIN(DATE)
                                  FROM table1 t3
                                  WHERE t3.DATE >= t1.DATE AND t3.ID > t1.ID)

Демо на dbfiddle

1 голос
/ 23 сентября 2019

Без LEAD и LAG вы можете написать его с помощью подзапроса, который будет извлекать дату из строки ID + 1, например:

SELECT qry.id
     , qry.focus
     , qry.date as startdate
     , (select sbq.date from your_table sbq where sbq.id = (qry.id + 1)) as enddate
  FROM your_table qry
1 голос
/ 23 сентября 2019

это должно сделать

select t.id, t.focus, t.date as startdate, t2.date as enddate 
from 
   (select focus, date, row_number() over (order by date asc)  as rn 
    from tableA) t
left join 
   (select focus, date, row_number() over (order by date asc) as rn from tableA) t2
       on t2.rn + 1 = t.rn
0 голосов
/ 23 сентября 2019

Я бы просто использовал коррелированный подзапрос:

select t.*,
       (select min(t2.date)
        from t t2
        where t2.date > t.date
       ) as enddate
from t;

Если у вас совпадают даты, вы можете использовать id для различения значений.Это будет:

select t.*,
       (select t2.date
        from t t2
        where t2.date > t.date or
              (t2.date = t.date and t2.id > t.id)
        order by t2.date asc, t2.id asc
        fetch first 1 row only
       ) as enddate
from t;

Примечание. Вы не указываете базу данных, которую используете.fetch first - это стандартный SQL;некоторые базы данных используют limit, другие используют select top.

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