Oracle 只列出发生变化的记录

Oracle list only records that changed

我有以下生成 table 的代码,如图所示:

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;

我已经尝试了以下方法,但没有return我需要的。

    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;

我想要实现的是仅列出 'code' 列中发生更改的记录(发生更改的记录之前和之后)。

所以结果集应该是这样的:

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;

最终结果集应仅包含突出显示的行。

更新 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;

不确定这是否有帮助我看不出任何相关性来整理您问题中的预期输出。

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;

以下脚本生成了预期的结果集:

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;