Автоинкрементное поле даты и версия oracle sql для таблицы - PullRequest
1 голос
/ 03 мая 2020

У меня есть таблица, и в этой таблице у меня есть данные, не загруженные должным образом, проблема целостности данных, так как это таблица измерений, мы должны правильно поддерживать значенияffective_dt_from иffective_dt_to и версию, ниже приведены таблица и пример данных

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 (81910,'chicago',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);
Insert into TEST values (81911,'chicago',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);
Insert into TEST values (81912,'chicago',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);
Insert into TEST values (81913,'chicago',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);
Insert into TEST values (81914,'chicago',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);

Запрос проверки целостности данных

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)

Результаты

CITY       POSTAL_CD   COUNT(*)

chicago    N/A         150

N/A        N/A          400

существующий набор данных

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO   VERSION
81910   CHICAGO    N/A        01.01.1900          31.12.2199    1
81911   CHICAGO    N/A        01.01.1900          31.12.2199    1
81912   CHICAGO    N/A        01.01.1900          31.12.2199    1
81913   CHICAGO    N/A        01.01.1900          31.12.2199    1
81914   CHICAGO    N/A        01.01.1900          31.12.2199    1

ожидаемый набор данных

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO   VERSION
81910   CHICAGO    N/A        01.01.1900          01.01.2017       1
81911   CHICAGO    N/A        01.01.2017          02.01.2017       2
81912   CHICAGO    N/A        02.01.2017          03.01.2017       3
81913   CHICAGO    N/A        03.01.1900          04.01.2017       4
81914   CHICAGO    N/A        04.01.2017          31.12.2199       5

после исправления и выполнения запроса проверки целостности данных я должен получить 0 строк

как это сделать я делаю EFFECTIVE_DT_FROM , EFFECTIVE_DT_TO и VERSION инкрементно, если бы было несколько записей, которые я бы вручную скорректировал и обновил, но у меня много строк, как чтобы исправить это?

Я попробовал следующий запрос, но это только обновит единственную версию, но не решит проблему

merge into TEST a
using
(
select LOC_SID,CITY,POSTAL_CD,EFFECTIVE_DT_FROM,EFFECTIVE_DT_TO,VERSION
,rank() over(partition by CITY,POSTAL_CD order by LOC_SID ) rnk
from TEST
where CITY='CHICAGO'
)b
on (a.LOC_SID = b.LOC_SID)
when matched then update set 
a.VERSION=b.rnk;

Я заметил, у меня есть сценарий

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

У меня 31 такой случай, когда я пытался Ваш запрос на слияние не работает, у меня есть следующий набор результатов

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.1900          31.12.2199          1
    25103   ASSAM   1290            01.01.1900          01.01.2017          1
    25104   ASSAM   1290            01.01.1900          31.12.2199          1
    25105   ASSAM   1310            01.01.1900          01.01.2017          1
    25106   ASSAM   1310            01.01.1900          31.12.2199          1
    25107   ASSAM   1781            01.01.1900          01.01.2017          1
    25108   ASSAM   1781            01.01.1900          31.12.2199          1
    25109   ASSAM   1982            01.01.1900          01.01.2017          1
    25110   ASSAM   1982            01.01.1900          31.12.2199          1

1 Ответ

0 голосов
/ 03 мая 2020

Я думаю, что ваши логики c, использующие merge и row_number(), находятся на правильном пути (хотя, по-видимому, предложение partition by не нужно, поскольку вы уже фильтруете по городу). Я расширил его дополнительными логами c для обработки дат:

  • начальные effective_dt_from и конечные effective_dt_to должны быть оставлены нетронутыми

  • между ними, вы хотите увеличивать даты изо дня в день, начиная с '2017-01-01'.

Запрос:

merge into test t
using (
    select
        t.*,
        row_number() over(order by loc_sid asc) rn,
        count(*) over() cnt
    from test t
    where city = 'Chicago'
) 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...