У меня есть таблица, и в этой таблице у меня есть данные, которые имеют проблемы с целостностью данных, так как это таблица измерений, которая нам нужна для правильного поддержания эффективных_dt_from и эффективных_dt_to и версии, ниже приведены таблица и образцы данных
create table TEST
(
LOC_SID NUMBER(38,0),
POSTAL_CD VARCHAR2(15 BYTE),
COUNTRY_CD_2CHAR VARCHAR2(2 BYTE),
CITY VARCHAR2(180 BYTE),
DISTRICT_CD VARCHAR2(120 BYTE),
POPULATION_APPROX VARCHAR2(15 BYTE),
EFFECTIVE_DT_FROM DATE,
EFFECTIVE_DT_TO DATE,
VERSION NUMBER(38,0)
);
образец данных
Insert into TEST values (81910,1234,UK,'Liverpool',50,1000,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('31.12.99 23:59:59','DD.MM.YY HH24:MI:SS'),1)
Insert into TEST values (81911,1234,UK,'Liverpool',50,0,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('31.12.99 23:59:59','DD.MM.YY HH24:MI:SS'),1)
Insert into TEST values (81912,4567,UK,'Liverpool',50,2000,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('31.12.99 23:59:59','DD.MM.YY HH24:MI:SS'),1)
Insert into TEST values (81913,4567,UK,'Liverpool',50,0,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('31.12.99 23:59:59','DD.MM.YY HH24:MI:SS'),1)
Запрос проверки целостности данных
SELECT count(*) AS RowAffected
FROM
(SELECT LOC_SID,
VERSION,
EFFECTIVE_DT_FROM,
EFFECTIVE_DT_TO,
CITY,
POSTAL_CD
FROM
(SELECT t.*,
LEAD(EFFECTIVE_DT_FROM, 1) OVER(PARTITION BY POSTAL_CD,COUNTRY_CD_2CHAR,CITY,DISTRICT_CD
ORDER BY EFFECTIVE_DT_FROM) AS next_date,
LEAD(VERSION, 1) OVER(PARTITION BY POSTAL_CD,COUNTRY_CD_2CHAR,CITY,DISTRICT_CD
ORDER BY EFFECTIVE_DT_FROM) AS next_version
FROM TEST t)
WHERE valid_to != next_date
OR VERSION = next_version)
Результаты
CITY POSTAL_CD COUNT(*)
Liverpool 1234 31
существующие данные
LOC_SID POSTAL_CD COUNTRY_CD_2CHAR CITY DISTRICT_CD POPULATION_APPROX EFFECTIVE_DT_FROM DATE EFFECTIVE_DT_TO VERSION
81910 1234 UK LIVERPOOL 50 1000 01.01.1900 31.12.2199 1
81921 1234 UK LIVERPOOL 50 0 01.01.1900 31.12.2199 1
81919 1234 UK LIVERPOOL 50 2000 01.01.1900 31.12.2199 1
81913 1234 UK LIVERPOOL 50 0 01.01.1900 31.12.2199 1
ожидаемые данные
LOC_SID POSTAL_CD COUNTRY_CD_2CHAR CITY DISTRICT_CD POPULATION_APPROX EFFECTIVE_DT_FROM DATE EFFECTIVE_DT_TO VERSION
81910 1234 UK LIVERPOOL 50 1000 01.01.1900 27.10.2016 1
81921 1234 UK LIVERPOOL 50 0 27.10.2016 28.10.2016 2
81919 1234 UK LIVERPOOL 50 2000 01.01.1900 31.12.2199 1
81913 1234 UK LIVERPOOL 50 0 27.10.2016 28.10.2016 2
Обратите внимание: у меня 131 запись в таблице с городом - Ливерпуль, и в основном у меня проблема с целостностью данных только для 31 записи. Приведенный выше пример - это просто пример с данными для нескольких записей для понимания (sid не в последовательности)
Я пробовал запрос ниже, но этот запрос обновляет все EFFECTIVE_DT_FROM, EFFECTIVE_DT_TO и версию, но мне нужно обновить только 31 запись (поскольку sid не в последовательности, мой запрос не будет работать), еще один момент, который следует упомянуть, в основном, я могу жестко запрограммировать sids (loc_sid), который является первичным ключом, но для этого мне нужно получить 62 ключа sid и включить в условие ниже, после того, как city = 'Liverpool и loc_sid in (1234,4567 ......) и запустить запрос он работает нормально, но я не хочу, нужно использовать некоторые logi c, loc_sids не в последовательности, я не смог понять это
merge into test t
using (
select
t.*,
row_number() over(order by loc_sid asc) rn,
count(*) over() cnt
from test t
where city = 'Liverpool'
) t1
on (t1.loc_sid = t.loc_id)
when matched the update set
t.version = t1.rn,
t.effective_dt_from =
case
when rn = 1 then t.effective_dt_from
else date '2016-10-27' + rn - 2
end,
t.effective_dt_to =
case
when rn = cnt then t.effective_dt_to
else date '2016-10-27' + rn - 1
end
, как это решить?