Как добавить строку в результат, если условие, основанное на двух соседних строках, истинно

#sql #postgresql

#sql #postgresql

Вопрос:

Учитывая таблицу, подобную этой

        system_time_start       |        system_time_end        | price 
------------------------------- ------------------------------- -------
 2020-11-26 00:59:05.079162-05 | 2020-11-26 23:48:45.030761-05 |  4.35 
 2020-11-26 23:48:45.030761-05 | 2020-11-27 00:26:02.198766-05 | 13.37 
 2020-11-27 00:29:26.116951-05 | 2020-11-27 00:36:22.072045-05 |  4.35 
 2020-11-27 00:36:22.072045-05 | infinity                      | 10.35 
 

Возможно ли это получить?

        system_time_start       | price 
------------------------------- -------
 2020-11-26 00:59:05.079162-05 |  4.35 
 2020-11-26 23:48:45.030761-05 | 13.37 
 2020-11-27 00:26:02.198766-05 |  null 
 2020-11-27 00:29:26.116951-05 |  4.35 
 2020-11-27 00:36:22.072045-05 | 10.35 
 

Прямо сейчас я выполняю постобработку таблицы с помощью цикла for, проверяя, system_time_start не равно ли значение предыдущей строки system_time_end , затем вставляю в результат другую строку с нулевой ценой, но мне интересно, есть ли способ сделать это в SQL. Я думал использовать lag функцию, которая может выполнить проверку, которую я хочу, но вставка строки между ними — это то, что я не могу понять, как это сделать.

Ответ №1:

Хммм … Вы можете использовать not exists :

 select
    system_time_start,
    price
from t
union all
select
    system_time_end,
    null
from t
where
    not exists (
        select
        from t as t2
        where t.system_time_end = t2.system_time_start
    ) and
    system_time_end != 'infinity'
order by system_time_start;
 

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

1. можете ли вы уточнить from t t2 синтаксис? это самосоединение?

2. @No_name . , , Это действительно предложение корреляции, но t2 это имя таблицы в подзапросе.

3. Спасибо! Это был умный способ подумать о проблеме.