аналитическая функция оракула через сравнение - PullRequest
0 голосов
/ 17 марта 2019

У меня есть таблица в базе данных оракула с данными, как показано ниже

G_DATE  P_KEY   P_STATUS    P_USER  P_CD
3/1/2019    1   old           a      bb
3/1/2019    2   old           b      ab
3/1/2019    3   new           c      cb
3/1/2019    4   med           c      cb
3/2/2019    1   old           a      bb
3/2/2019    2   old           b      ab
3/2/2019    3   new           c      cb
3/2/2019    4   med           c      cb
3/3/2019    1   old           a      bb
3/3/2019    2   new           d      ab
3/3/2019    3   med           d      cb
3/3/2019    4   new           c      cb
3/4/2019    1   med           d      bb
3/4/2019    2   old           d      xy
3/4/2019    3   med           d      cb
3/4/2019    5   new           c      cb
3/5/2019    1   old           a      bb
3/5/2019    2   new           d      ab
3/5/2019    3   med           d      cb
3/5/2019    5   new           c      xy

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

похоже, что мы создаем медленно меняющуюся таблицу измерений с эффективными и конечными датами, которые заполняются всякий раз, когда происходит изменение в любом из этих 3 атрибутов. p_STATUS, p_cD, P_UsER естественный ключ - это g_date и p_key. Если вы заметили вывод, который я опубликовал, мы должны отследить изменения для любого изменения атрибута для заданных p_key и g_date.

Первичным ключом вышеприведенной таблицы является p_key и g_date, и для каждого изменения в p_status, p_user и p_cd необходимо выбирать новую строку с eff_dt и end_dt соответственно для каждой комбинации g_date и p_key. Не могли бы вы помочь мне с некоторыми идеями о том, как достичь ниже результата

P_KEY   P_STATUS    P_USER  P_CD    eff_dt      end_dt  latest_row_flag
1       old         a       bb      3/1/2019    3/3/2019    N
1       med         d       bb      3/4/2019    3/4/2019    N
1       old         a       bb      3/5/2019    12/31/4712  Y
2       old         b       ab      3/1/2019    3/2/2019    N
2       new         d       ab      3/3/2019    3/3/2019    N
2       old         d       xy      3/4/2019    3/5/2019    N
2       new         d       ab      3/5/2019    12/31/4712  Y
3       new         c       cb      3/1/2019    3/2/2019    N
3       med         d       cb      3/3/2019    12/31/4712  Y
4       med         c       cb      3/1/2019    3/2/2019    N
4       new         c       cb      3/3/2019    12/31/4712  Y
5       new         c       cb      3/4/2019    3/4/2019    N
5       new         c       xy      3/5/2019    12/31/4712  Y

---- скрипты для создания таблицы и вставки строк в таблицу

create table work_audit
( g_date date, 
  P_key  number, 
  P_status varchar2(10),
  p_user  varchar2(10),
  p_cd varchar2(10) 
);

SET DEFINE OFF;
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/1/2019', 'MM/DD/YYYY'), 1, 'old', 'a', 'bb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/1/2019', 'MM/DD/YYYY'), 3, 'new', 'c', 'cb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/1/2019', 'MM/DD/YYYY'), 4, 'med', 'c', 'cb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/1/2019', 'MM/DD/YYYY'), 2, 'old', 'b', 'ab');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/2/2019', 'MM/DD/YYYY'), 3, 'new', 'c', 'cb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/2/2019', 'MM/DD/YYYY'), 1, 'old', 'a', 'bb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/2/2019', 'MM/DD/YYYY'), 2, 'old', 'b', 'ab');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/2/2019', 'MM/DD/YYYY'), 4, 'med', 'c', 'cb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/3/2019', 'MM/DD/YYYY'), 1, 'old', 'a', 'bb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/3/2019', 'MM/DD/YYYY'), 2, 'new', 'd', 'ab');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/3/2019', 'MM/DD/YYYY'), 3, 'med', 'd', 'cb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/3/2019', 'MM/DD/YYYY'), 4, 'new', 'c', 'cb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/4/2019', 'MM/DD/YYYY'), 1, 'med', 'd', 'bb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/4/2019', 'MM/DD/YYYY'), 2, 'old', 'd', 'xy');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/4/2019', 'MM/DD/YYYY'), 3, 'med', 'd', 'cb');
Insert into WORK_AUDIT
   (G_DATE, P_KEY, P_STATUS, P_USER, P_CD)
 Values
   (TO_DATE('3/4/2019', 'MM/DD/YYYY'), 5, 'new', 'c', 'cb');

COMMIT;

1 Ответ

1 голос
/ 17 марта 2019

Если я правильно понимаю, это проблема пробелов и островков.

Это должно делать то, что вы хотите:

select p_key, p_status, p_user, p_cd, min(g_date) as start_dt,
       (case when max_g_date = max(g_date) then date '4712-12-31' else max(g_date) end) as end_dt,
       (case when max_g_date = max(g_date) then 1 else 0 end) as latest_row_flag
from (select wa.*,
             row_number() over (partition by p_key order by g_date) as seqnum,
             row_number() over (partition by p_key, p_status, p_user, p_cd order by g_date) as seqnum_2,
             max(g_date) over () as max_g_date
      from work_audit wa
     ) wa
group by p_key, p_status, p_user, p_cd, (seqnum - seqnum_2), max_g_date
order by p_key, min(g_date);

Здесь - это дБ.<> скрипка.Скрипка использует Postgres, потому что Oracle не так хорошо работает с db <> fiddle.Но запрос не меняется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...