我有一个包含日期和状态的表格。我希望获得状态更改为最新状态的日期。样本数据:
DATE STATUS
01/01/2000 P
02/01/2000 A
03/01/2000 C
04/01/2000 A
05/01/2000 A
06/01/2000 A
因此,在这种情况下,最近的状态是A,并在04/01/2000更改为此状态。 (在这种情况下应该忽略02/01/2000行)
有关如何选择此行的任何建议?
答案 0 :(得分:0)
起初,我误解了这个问题。您需要获取最后一次状态的最早日期。
您可以使用技巧对相似状态的序列进行分组 - 行数的差异。对于相同的序列,差异(在下面的查询中)是不变的。然后,您可以使用聚合来获取最小日期并选择最新日期:
def julian_day(dt):
jan1 = dt.replace(month=1, day=1)
return 1 + (dt - jan1).days
编辑:
无论如何,正确的方法是使用select mindate
from (select min(date) as mindate
from (select t.*,
row_number() over (order by date) as seqnum1,
row_number() over (partition by status order by date) as seqnum2
from table t
) t
group by status, (seqnum1 - seqnum2)
order by mindate desc
) t
where rownum = 1
:
lag()
Here是SQL小提琴。
答案 1 :(得分:0)
你可以使用lag或lead来做到这一点。在这里,我使用lead,按日期降序排序以查找上一个状态日期(如果它为null我只提供日期,如果只有一条记录则需要该日期。)
select max(date)
from (
select status, date, nvl(lead(status) over (order by date desc),date) as previous_status
from t
order by date desc
)
where status <> previous_status;
答案 2 :(得分:0)
这样的事情应该做到这一点:
with sample_data as (select to_date('01/01/2000', 'dd/mm/yyyy') dt, 'P' status from dual union all
select to_date('02/01/2000', 'dd/mm/yyyy') dt, 'A' status from dual union all
select to_date('03/01/2000', 'dd/mm/yyyy') dt, 'C' status from dual union all
select to_date('04/01/2000', 'dd/mm/yyyy') dt, 'A' status from dual union all
select to_date('05/01/2000', 'dd/mm/yyyy') dt, 'A' status from dual union all
select to_date('06/01/2000', 'dd/mm/yyyy') dt, 'A' status from dual),
results1 as (select dt,
status,
row_number() over (order by dt) - row_number() over (partition by status order by dt) grp
from sample_data),
results2 as (select status, min(dt) min_dt, grp, max(min(dt)) over () max_min_dt
from results1
group by status, grp)
select status, min_dt
from results2
where min_dt = max_min_dt;
STATUS MIN_DT
------ ----------
A 04/01/2000