问题
Say I have a table, something like
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
There are other fields, but I made it simple. So I create a query where i have the date in descending order. I was to return the row where there was a change in CCTR. So in this case it would return ID 4. Basically i want to find the previous value of CCTR before it changed, in this case from 2B to 2C.
How do I do this? Ive tried to google it, but can't seem to find the right method.
回答1:
You can use the LAG()
window function to peek at the previous row and compare it. If your data is:
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');
Then the query would be:
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
);
Result:
ID CCTR DATE1
------- ---------- -------------------
4 2B 2017-03-02 00:00:00
回答2:
You may use first_value
analytic function to detect the changes in CCTR column :
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
来源:https://stackoverflow.com/questions/52314749/oracle-get-row-where-column-value-changed