Oracle список только записей, которые изменились - PullRequest
0 голосов
/ 07 мая 2019

У меня есть следующий код, который создает таблицу, как показано на рисунке:

with test (code, datum) as
      (select 600, date '2018-02-01' from dual union all
       select 600, date '2018-02-02' from dual union all
       select 0, date '2018-02-03' from dual union all
       select 0, date '2018-02-04' from dual union all
       select 0, date '2018-02-05' from dual union all
       select 600, date '2018-02-06' from dual union all
       select 600, date '2018-02-07' from dual union all
       select 0, date '2018-02-08' from dual union all
       select 0, date '2018-02-09' from dual
      )

    select * from test;

Я пробовал следующее, но не возвращает то, что мне нужно.

    select * from (
    select test.*, min(datum) over (partition by code order by code) as min_date, 
    max(datum) over (partition by code order by code) as max_date  
    from test) where min_date = datum;

enter image description here

Чего я хотел бы добиться, так это перечислить только записи, в которых произошли изменения в столбце «код» (до и после записигде происходит изменение).

Таким образом, набор результатов должен выглядеть следующим образом:

02/FEB/18 00:00:00  600
03/FEB/18 00:00:00  0
05/FEB/18 00:00:00  0
06/FEB/18 00:00:00  600
07/FEB/18 00:00:00  600
08/FEB/18 00:00:00  0

Я ссылался на этот вопрос, но он не решает ту же проблему, что и у меня.

вопрос

Любая помощь приветствуется, спасибо.

ОБНОВЛЕНИЕ:

Это ближе к тому, чего я хотел бы достичь.Я могу перечислить все строки, где столбцы код и изменения не совпадают.Однако мне нужно перечислить запись после того, где эти значения также отличаются.

with test (code, datum) as
  (select 600, date '2018-02-01' from dual union all
   select 600, date '2018-02-02' from dual union all
   select 0, date '2018-02-03' from dual union all
   select 0, date '2018-02-04' from dual union all
   select 0, date '2018-02-05' from dual union all
   select 600, date '2018-02-06' from dual union all
   select 600, date '2018-02-07' from dual union all
   select 0, date '2018-02-08' from dual union all
   select 0, date '2018-02-09' from dual
  )
  ,y1 as (
    select test.datum, test.code, lead(code) over (order by datum) as change
    from test
  )
select * from y1;

enter image description here

enter image description here

Окончательный набор результатов должен содержать только выделенные строки.

enter image description here

ОБНОВЛЕНИЕ 2:

Я думаю, что я, возможно, понял это правильно, все еще нужно проверить, но это, кажется, работает:

 with test (code, datum) as
      (select 600, date '2018-02-01' from dual union all
       select 600, date '2018-02-02' from dual union all
       select 0, date '2018-02-03' from dual union all
       select 0, date '2018-02-04' from dual union all
       select 0, date '2018-02-05' from dual union all
       select 600, date '2018-02-06' from dual union all
       select 600, date '2018-02-07' from dual union all
       select 0, date '2018-02-08' from dual union all
       select 0, date '2018-02-09' from dual
      )
      ,y1 as (
        select test.datum, test.code, lag(nvl(code,code)) over (order by datum) as after, lead(nvl(code,code)) over (order by datum) as before
        from test
      )
      select * from y1 where code != before or code != after;

Ответы [ 2 ]

0 голосов
/ 07 мая 2019

Следующий скрипт выдает ожидаемый набор результатов:

with test (code, datum) as
      (select 600, date '2018-02-01' from dual union all
       select 600, date '2018-02-02' from dual union all
       select 0, date '2018-02-03' from dual union all
       select 0, date '2018-02-04' from dual union all
       select 0, date '2018-02-05' from dual union all
       select 600, date '2018-02-06' from dual union all
       select 600, date '2018-02-07' from dual union all
       select 0, date '2018-02-08' from dual union all
       select 0, date '2018-02-09' from dual
      )
      ,y1 as (
        select test.datum, test.code, lag(nvl(code,code)) over (order by datum) as after, lead(nvl(code,code)) over (order by datum) as before
        from test
      )
      select * from y1 where code != before or code != after;
0 голосов
/ 07 мая 2019

Не уверен, поможет ли это, но я не вижу никакой релевантности, чтобы отсортировать ожидаемый результат в вашем вопросе.

with test (code, datum) as
  (select 600, date '2018-02-01' from dual union all
   select 600, date '2018-02-02' from dual union all
   select 0, date '2018-02-03' from dual union all
   select 0, date '2018-02-04' from dual union all
   select 0, date '2018-02-05' from dual union all
   select 600, date '2018-02-06' from dual union all
   select 600, date '2018-02-07' from dual union all
   select 0, date '2018-02-08' from dual union all
   select 0, date '2018-02-09' from dual
  )
  ,y1 as (
    select test.datum, test.code, lead(code) over (order by datum) as change
    from test
    UNION 
    select test.datum, test.code, lag(code) over (order by datum) as change
    from test

  )
select * from y1 
where change = 600;
...