Oracle获取行,其中列值已更改

时间:2018-09-13 13:26:57

标签: sql oracle

说我有一张桌子,类似

ID     CCTR    DATE
-----  ------  ----------
1      2C      8/1/2018
2      2C      7/2/2018
3      2C      5/4/2017
4      2B      3/2/2017
5      2B      1/1/2017
6      UC      11/23/2016

还有其他字段,但我使其变得简单。因此,我创建了一个查询,其中我的日期按降序排列。我要返回CCTR发生变化的那一行。因此,在这种情况下,它将返回ID4。基本上,我想在更改之前将CCTR的值找回,在这种情况下,是从2B到2C。

我该怎么做?香港专业教育学院试图用谷歌搜索它,但似乎找不到正确的方法。

2 个答案:

答案 0 :(得分:1)

您可以使用LAG()窗口函数来窥视上一行并进行比较。如果您的数据是:

create table t2 (
  id number(6),
  cctr varchar2(10),
  date1 date
);

insert into t2 (id, cctr, date1) values (1, '2C', date '2018-08-01');
insert into t2 (id, cctr, date1) values (2, '2C', date '2018-07-02');
insert into t2 (id, cctr, date1) values (3, '2C', date '2017-05-04');
insert into t2 (id, cctr, date1) values (4, '2B', date '2017-03-02');
insert into t2 (id, cctr, date1) values (5, '2B', date '2017-01-01');
insert into t2 (id, cctr, date1) values (6, 'UC', date '2016-11-23');

然后查询将是:

select * from t2 where date1 = (
  select max(date1)
    from (
    select 
      id, date1, cctr, lag(cctr) over(order by date1 desc) as prev
      from t2
    ) x  
    where prev is not null and cctr <> prev
);

结果:

ID       CCTR        DATE1    
-------  ----------  -------------------
4        2B          2017-03-02 00:00:00  

答案 1 :(得分:1)

您可以使用first_value分析功能来检测 CCTR 列中的更改:

select fv as value, cctr
  from 
(
  with t(ID,CCTR) as
  (
   select 1,'2C' from dual union all
   select 2,'2C' from dual union all
   select 3,'2C' from dual union all
   select 4,'2B' from dual union all
   select 5,'2B' from dual union all
   select 6,'UC' from dual
  ) 
  select id, cctr, first_value(id) over (partition by cctr order by id ) fv
    from t
  order by id
)  
where id = fv;

VALUE  CCTR
-----  ----
  1     2C
  4     2B
  6     UC

Rextester Demo