【发布时间】:2019-05-07 04:22:54
【问题描述】:
我有以下代码生成一个如图所示的表格:
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;
我想要实现的是仅列出“代码”列上发生更改的记录(发生更改的记录之前和之后)。
所以结果集应该是这样的:
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;
【问题讨论】:
-
What I would like to achieve is list only the records where a change occurs on the 'code' column-- 识别列发生变化的机制是什么? -
本质上,我们使用的是按升序排列的基准列。因此它将从第一行开始,当代码发生更改时,它将打印更改之前的行以及更改之后的行。简而言之,随着时间(数据)的移动显示代码的旧值和新值。
标签: sql oracle gaps-and-islands