Data Integrity SQL запрос для исправления ошибки в таблице - PullRequest
0 голосов
/ 25 апреля 2020

В настоящее время я сталкиваюсь с проблемой целостности данных в одной из таблиц из таблицы измерений, ниже приведены сведения

create table TEST_TBL
(
JOB_ID  NUMBER(38,0),
LOC_SID NUMBER(38,0),
CITY VARCHAR2(180 BYTE),
CITY_NM_CLR VARCHAR2(50 BYTE),
CITY_NM_OFFICIAL VARCHAR2(180 BYTE),
DISTRICT VARCHAR2(120 BYTE),
DISTRICT_CD VARCHAR2(20 BYTE),
IN_CNTRY_REG VARCHAR2(100 BYTE),
CNTRY_NM VARCHAR2(255 BYTE),
POSTAL_CD VARCHAR2(15 BYTE),
POPUL_APROX VARCHAR2(15 BYTE),
LONGITUDE NUMBER,
LATITUDE NUMBER,
GLOBAL_REG VARCHAR2(40 BYTE),
CNTRY_CD_2CHAR  VARCHAR2(2 BYTE),
CNTRY_CD_3CHAR  VARCHAR2(3 BYTE),
CNTRY_CD_NUMER  VARCHAR2(3 BYTE),
CNTRY_NM_OFFICIAL VARCHAR2(255 BYTE),
CNTRY_CALL_CD VARCHAR2(10 BYTE),
BANK_CNTRY_CD NUMBER(38,0),
CONTINENT VARCHAR2(30 BYTE),
MONETARY_REG VARCHAR2(40 BYTE),
EFFECTIVE_DT_FROM DATE,
EFFECTIVE_DT_TO DATE,
VERSION NUMBER(38,0),
UPDATED_BY_ETL_JOB NUMBER(38,0)
);

Insert into TEST_TBL values (1234,'81910','N/A',null,'N/A','N/A','0','N/A','USA','N/A','0','0','0','NA','EN','ENG','001',null,'91','0','North_America',null,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',null);

Обратите внимание:

Уникальный индекс уже присвоен LOC_SID ( первичный ключ) неуникальный индекс уже используется для следующих столбцов CITY_NM_CLR, CNTRY_CD_2CHAR

Текущая ситуация

, когда я проверяю проблему целостности из таблицы, я получаю много записей приблизительно 300+ (выше та же запись набора данных)

Ниже приведен запрос sql, который я использую для проверки целостности

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 CITY, POSTAL_CD
                                             ORDER BY EFFECTIVE_DT_FROM) AS next_date,
             LEAD(VERSION, 1) OVER(PARTITION BY CTY, POSTAL_CD
                                   ORDER BY EFFECTIVE_DT_FROM) AS next_version
      FROM TEST_TBL t)
   WHERE valid_to != next_date
     OR VERSION = next_version)

после исправления, когда я запускаю вышеуказанный запрос, он не должен возвращать никаких результат

Позвольте мне дать обзор подсчетов с образцами данных

CITY       POSTAL_CD   COUNT(*)

N/A         N/A       502

TOKYO       N/A       30

HABSIGUDA   3452      2

DELHI       N/A       4

ASSAM       1153      1

ASSAM       1290      1

ASSAM       1310      1

ASSAM       1781      1

ASSAM       1982      1

Образцы данных

сценарий - 1

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM  EFFECTIVE_DT_TO  VERSION
82141   N/A     N/A         01.01.1900         31.12.2199       1
82142   N/A     N/A         01.01.1900         31.12.2199       1

у меня 400 таких строк

сценарий - 2

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO   VERSION
46211   TOKYO    N/A        01.01.1900          31.12.2199    1
46212   TOKYO    N/A        01.01.1900          31.12.2199    1

у меня 30 таких строк

сценарий - 3

 LOC_SID CITY       POSTAL_CD  EFFECTIVE_DT_FROM  EFFECTIVE_DT_TO  VERSION
 57372  HABSIGUDA   3452  01.01.1900          29.12.2017             1
 61321  HABSIGUDA   3452  29.12.2017          31.12.2199             2
 67371  UPPAL       4922  01.01.1900          31.12.2199             1
 80737  HABSIGUDA   3452  01.01.1900          31.12.2199             1

у меня всего одна строка

сценарий - 4

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO  VERSION
4822    DELHI   N/A         01.01.1900          31.12.2199     1
4825    DELHI   3911        01.01.1900          31.12.2199     1
4826    DELHI   N/A         01.01.1900          31.12.2199     1
4827    DELHI   N/A         01.01.1900          31.12.2199     1
4828    DELHI   N/A         01.01.1900          31.12.2199     1
4829    DELHI   N/A         01.01.1900          31.12.2199     1

у меня есть 4 строки

Сценарий - 5

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO  VERSION
25101   ASSAM   1153            01.01.1900          31.12.2199     1
25102   ASSAM   1153            01.01.1900          31.12.2199     1
25103   ASSAM   1290            01.01.1900          31.12.2199     1
25104   ASSAM   1290            01.01.1900          31.12.2199     1
25105   ASSAM   1310            01.01.1900          31.12.2199     1
25106   ASSAM   1310            01.01.1900          31.12.2199     1
25107   ASSAM   1781            01.01.1900          31.12.2199     1
25108   ASSAM   1781            01.01.1900          31.12.2199     1
25109   ASSAM   1982            01.01.1900          31.12.2199     1
25110   ASSAM   1982            01.01.1900          31.12.2199     1

у меня есть 300 строк

в основном LOC_SID - это PK и инкрементный, так что после ожидаемой версии является инкрементным, ниже ожидаемый результат после выполнения оператора update затем в таблице БД

** результаты (после выполнения оператора update) *** сценарий 1069 *

- 4

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO  VERSION
4822    DELHI   N/A         01.01.1900          01.01.1900         1
4825    DELHI   3911        01.01.1900          31.12.2199         1
4826    DELHI   N/A         01.01.1900          01.01.1900         2
4827    DELHI   N/A         01.01.1900          01.01.1900         3
4828    DELHI   N/A         01.01.1900          01.01.1900         4
4829    DELHI   N/A         01.01.1900          01.01.1900         5

1 Ответ

0 голосов
/ 25 апреля 2020

Возьмите backup вашего стола TEST_TBL и попробуйте следующее

Делайте следующие два UPDATE, пока не получите zero rows обновление

    BEGIN
    WHILE(1=1)
    LOOP 
    UPDATE TEST_TBL a 
    set version=(select prev_version+1 from   
                             (
                            SELECT
                        t.*,
                      ROWID,
                      Lag(version, 1)
                        over(
                          PARTITION BY cty, postal_cd
                          ORDER BY effective_dt_from) AS prev_version
                         from TEST_TBL T)t
                         where a.rowid=t.rowid 
                        AND a.version <=t.prev_version)
    WHERE EXISTS (select 1 from  (
                            SELECT
                        t.*,
                      ROWID,
                      Lag(version, 1)
                        over(
                          PARTITION BY cty, postal_cd
                          ORDER BY effective_dt_from) AS prev_version
                         from TEST_TBL T)t
                         where a.rowid=t.rowid 
                        AND a.version <=t.prev_version);
    commit;
    EXIT WHEN SQL%ROWCOUNT=0; 
    END LOOP;
    END;

Второе обновление

    BEGIN
    WHILE(1=1)
    LOOP
    UPDATE TEST_TBL b
    set valid_to=(select next_date from 
                             (
                            SELECT
                        t.*,
                      ROWID,
                      LEAD(EFFECTIVE_DT_FROM, 1) OVER(PARTITION BY CITY, POSTAL_CD
                                                 ORDER BY EFFECTIVE_DT_FROM) AS next_date
                         from test_tbl T)t
                         where b.rowid=t.rowid 
                        AND valid_to != next_date)
    WHERE EXISTS (select 1 from   (
                            SELECT
                        t.*,
                      ROWID,
                      LEAD(EFFECTIVE_DT_FROM, 1) OVER(PARTITION BY CITY, POSTAL_CD
                                                 ORDER BY EFFECTIVE_DT_FROM) AS next_date
                         from test_tbl T)t
                         where b.rowid=t.rowid 
                        AND valid_to != next_date);
                        commit;
    EXIT WHEN SQL%ROWCOUNT=0; 
    END LOOP;
    END;
...