Data Integrity issue query fix logic oracle sql

痴心易碎 提交于 2020-05-17 07:09:27

问题


I have a table and in this table i have data is not properly loaded data integrity issue ,since this is a dimension table we need to maintain the effective_dt_from and effective_dt_to and version correctly ,below is the table and sample data

create table TEST (
    LOC_SID NUMBER(38,0),
    CITY VARCHAR2(180 BYTE),
    POSTAL_CD VARCHAR2(15 BYTE),
    EFFECTIVE_DT_FROM DATE,
    EFFECTIVE_DT_TO DATE,
    VERSION NUMBER(38,0)
);

Insert into TEST values (25101,'Assam',1153,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('01.01.17 23:59:59','DD.MM.YY HH24:MI:SS'),1);
Insert into TEST values (25102,'Assam',1153,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 (25103,'Assam',1290,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('01.01.17 23:59:59','DD.MM.YY HH24:MI:SS'),1);
Insert into TEST values (25104,'Assam',1290,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 (25105,'Assam',1310,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('01.01.17 23:59:59','DD.MM.YY HH24:MI:SS'),1);
Insert into TEST values (25106,'Assam',1310,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 (25107,'Assam',1781,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('01.01.17 23:59:59','DD.MM.YY HH24:MI:SS'),1);
Insert into TEST values (25108,'Assam',1781,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 (25109,'Assam',1982,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('01.01.17 23:59:59','DD.MM.YY HH24:MI:SS'),1);
Insert into TEST values (25110,'Assam',1982,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);

Data integrity check query

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 t)
   WHERE valid_to != next_date
     OR VERSION = next_version)

existing data set

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

expected data set

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

i tried the below query ,but this will only update the only version ,but doesn't fix the issue

merge into test t
using (
    select
        t.*,
        row_number() over(order by loc_sid asc) rn,
        count(*) over() cnt
    from test t
    where city = 'Assam'
) 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 '2017-01-01' + rn - 2
        end,
    t.effective_dt_to = 
        case 
            when rn = cnt then t.effective_dt_to
            else date '2017-01-01' + rn - 1
        end

回答1:


The logic is fine for the dates, however you need row_number() over postal_cd partitions to manage the version:

merge into test t
using (
    select
        loc_sid,
        row_number() over(order by loc_sid asc) rn,
        count(*) over() cnt,
        row_number() over(partition by postal_cd order by loc_sid) version
    from test t
    where city = 'Assam'
) t1
on (t1.loc_sid = t.loc_sid)
when matched then update set
    t.version = t1.version,
    t.effective_dt_from = 
        case 
            when rn = 1 then t.effective_dt_from
            else date '2017-01-01' + rn - 2
        end,
    t.effective_dt_to = 
        case 
            when rn = cnt then t.effective_dt_to
            else date '2017-01-01' + rn - 1
        end

Demo on DB Fiddle:

LOC_SID | CITY  | POSTAL_CD | EFFECTIVE_DT_FROM | EFFECTIVE_DT_TO | VERSION
------: | :---- | :-------- | :---------------- | :-------------- | ------:
  25101 | Assam | 1153      | 01-JAN-00         | 01-JAN-17       |       1
  25102 | Assam | 1153      | 01-JAN-17         | 02-JAN-17       |       2
  25103 | Assam | 1290      | 02-JAN-17         | 03-JAN-17       |       1
  25104 | Assam | 1290      | 03-JAN-17         | 04-JAN-17       |       2
  25105 | Assam | 1310      | 04-JAN-17         | 05-JAN-17       |       1
  25106 | Assam | 1310      | 05-JAN-17         | 06-JAN-17       |       2
  25107 | Assam | 1781      | 06-JAN-17         | 07-JAN-17       |       1
  25108 | Assam | 1781      | 07-JAN-17         | 08-JAN-17       |       2
  25109 | Assam | 1982      | 08-JAN-17         | 09-JAN-17       |       1
  25110 | Assam | 1982      | 09-JAN-17         | 31-DEC-99       |       2


来源:https://stackoverflow.com/questions/61581527/data-integrity-issue-query-fix-logic-oracle-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!