Oracle仅列出已更改的记录

时间:2019-05-07 04:22:55

标签: sql oracle gaps-and-islands

我有以下代码生成一张表,如图所示:

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

我提到了这个问题,但并没有解决我遇到的相同问题。

question

任何帮助表示感谢,谢谢。

更新:

这更接近我想要实现的目标。我可以列出列代码和更改不相同的所有行。但是,我需要在这些值也不同的地方列出记录。

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 :(得分:0)

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

.m2

答案 1 :(得分: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, 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;