Самый простой ответ - удалить поле ValidTo
, которое фактически является производным полем (которое обычно хранить не предполагается).Затем вам нужно только вставить соответствующие записи, и вы можете получить необходимое значение довольно тривиально (требуется агрегированное самостоятельное объединение).
Однако меня немного беспокоит, что вы переопределяете данное ValidFrom
дата, если запись существует - вы фактически делаете невозможным задний ход истории, и новые записи всегда будут «новыми и действующими в настоящее время», что крайне маловероятно.Во-первых, если вы когда-либо вставляете несколько записей, у вас может не быть порядка вставки, который будет гарантированно поставлен, что быстро сработает с этим.Это также делает невозможным заднюю дату записей, если это необходимо (примечание: это не обязательно для гнусных целей - иногда есть веские деловые причины для того, чтобы задним числом «подходящую» историю задним числом. Однако, добавьте метку времени записи для аудита).Кроме того, что происходит, когда у вас есть несколько записей для одного и того же дня - как вы узнаете, какая из них была правильной (поэтому вы уверены, что на самом деле вам не нужна временная метка)?
Кроме этого, вот дваоператоры (проверено в DB2) Я бы использовал для изменения таблицы, как вы описали.
Во-первых, оператор вставки, чтобы позаботиться о новых записях:
INSERT INTO AccountHistory (Account_FK, ValidTo, ValidFrom)
SELECT a.Account_FK, CASE WHEN b.Account_FK IS NULL
THEN a.ValidTo
ELSE NULL END,
CASE WHEN b.Account_FK IS NULL
THEN a.ValidFrom
ELSE CURRENT_DATE END
FROM SomeOtherTable as a
LEFT JOIN (SELECT DISTINCT Account_FK
FROM AccountHistory) as b
ON b.Account_FK = a.Account_FK
И оператор обновления для заполнения 'ValidTo'даты (это получает все, а не только то, что было вставлено):
UPDATE AccountHistory as a SET ValidTo = (SELECT MIN(b.ValidFrom)
FROM AccountHistory as b
WHERE a.Account_FK = b.Account_FK
AND b.ValidFrom > a.ValidFrom)
WHERE ValidTo IS NULL
AND EXISTS (SELECT '1'
FROM AccountHistory as b
WHERE a.Account_FK = b.Account_FK
AND b.ValidFrom > a.ValidFrom)