Исправление ошибки запроса целостности данных для перезаписи sql - PullRequest
1 голос
/ 06 мая 2020

У меня есть таблица, и в этой таблице у меня есть данные, которые имеют проблемы с целостностью данных, поскольку это таблица измерений, которая нам нужна для правильного поддержания effective_dt_from и effective_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 не в последовательности)

Я пробовал запрос ниже, но этот запрос обновляет все E FFECTIVE_DT_FROM, EFFECTIVE_DT_TO и version, но мне нужно обновить только 31 запись (так как sid не последовательно, мой запрос не будет работать).

Еще один момент, о котором стоит упомянуть, - это, по сути, я могу жестко закодировать sids (loc_sid ), который является первичным ключом, но для этого мне нужно получить 62 si d и включите в приведенное ниже условие после where city='Liverpool and 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

как решить это?

...