Postgres UPSERT Изменить конфликт, затем вставить запись - PullRequest
0 голосов
/ 13 февраля 2019

Я борюсь с созданием сценария UPSERT, который при конфликте (1) изменяет существующую запись, чтобы избежать конфликта, а затем (2) вставляет новую запись.Я пытаюсь построить таблицу, которая поддерживает момент времени точность при сохранении места.Теория заключается в том, что более эффективно правильно фиксировать изменение данных, а не захватывать дублирующиеся фрагменты данных, которые не меняются.

Я создал пример, чтобы помочь указать на то, что я пытаюсь сделать.Есть три гонщика, которые находятся на определенной трассе в течение определенного периода времени.Один из водителей решает сменить маршрут, а двое других решают остаться там, где они есть.В какой-то более поздний момент времени четвертый водитель входит в картину.

Я хотел бы иметь возможность запросить таблицу и сказать «кто был на какой дорожке в этот день?»

Надеюсьэто имеет смысл.

Заранее спасибо.

----------------------Set up an example table
create table drivers(
firstName varchar(30)
,lastName varchar(30)
,raceTrack varchar(30)
,effectiveDate date 
,expirationDate date
);

insert into drivers
select 'ricky', 'bobby', 'talladega', cast('2019-01-01' as date), cast('9999-12-31' as date)
union
select 'cal', 'naughton', 'martinsville', cast('2019-01-01' as date), cast('9999-12-31' as date)
union
select 'jean', 'girard', 'daytona', cast('2019-01-01' as date), cast('9999-12-31' as date);

----------------------Expire the daytona record for Jean
----This is the UPDATE portion of the UPSERT and triggers a conflict with the UPSERT since firstname and lastname match. 
update drivers set expirationdate = cast('2019-02-10' as date)
where firstname = 'jean' and lastname = 'girard';

----------------------Insert new circuit de monaco record for Jean
----This is the INSERT portion of the UPSERT
insert into drivers
select 'jean', 'girard', 'circuit de monaco', cast('2019-02-11' as date), cast('9999-12-31' as date);

----------------------A new driver comes into the data
----This is an example of the expected behavior without a conflict
insert into drivers
select 'reese', 'bobby', 'greenville pickens', cast('2019-02-12' as date), cast('9999-12-31' as date);

----------------------Query all of the driver and track records for some day in January 2019

select * 
from drivers
where cast('2019-01-11' as date) between effectivedate and expirationdate;

----------------------Query all of the driver and track records for some day in February 2019

select * 
from drivers
where cast('2019-02-11' as date) between effectivedate and expirationdate;

select * 
from drivers
where cast('2019-02-12' as date) between effectivedate and expirationdate;
...