如何只选择最新的条目?

时间:2015-03-30 08:36:35

标签: sql oracle greatest-n-per-group

我有这样的表:

IST | FILEDATE  | DATE                | ...
1   | 2013-2014 | 27.03.2015 10:20:47 | ...
2   | 2013-2014 | 27.03.2015 10:20:47 | ...
3   | 2013-2014 | 27.03.2015 10:20:47 | ...
1   | 2013-2014 | 28.03.2015 11:20:47 | ...
2   | 2013-2014 | 28.03.2015 11:20:47 | ...
3   | 2013-2014 | 28.03.2015 11:20:47 | ...
1   | 2014-2015 | 29.03.2015 12:20:47 | ...
2   | 2014-2015 | 29.03.2015 12:20:47 | ...
3   | 2014-2015 | 29.03.2015 12:20:47 | ...
...

我需要选择所有IST的最新(带日期值)条目,如下所示:

IST | FILEDATE  | DATE                | ...
1   | 2014-2015 | 29.03.2015 11:20:47 | ...
2   | 2014-2015 | 29.03.2015 11:20:47 | ...
3   | 2014-2015 | 29.03.2015 11:20:47 | ...

我尝试了order byrownum=1,但它仅适用于单一IST。

我该怎么做?谢谢。

3 个答案:

答案 0 :(得分:3)

这是分析函数(也就是窗口函数)真正有用的典型场景:

with v_data(ist, filedate, entry_date) as (
  select 1, '2013-2014', to_date('27.03.2015 10:20:47','DD.MM.YYYY hh24:mi:ss') from dual union all 
  select 2, '2013-2014', to_date('27.03.2015 10:20:47','DD.MM.YYYY hh24:mi:ss') from dual union all 
  select 3, '2013-2014', to_date('27.03.2015 10:20:47','DD.MM.YYYY hh24:mi:ss') from dual union all 
  select 1, '2013-2014', to_date('28.03.2015 11:20:47','DD.MM.YYYY hh24:mi:ss') from dual union all 
  select 2, '2013-2014', to_date('28.03.2015 11:20:47','DD.MM.YYYY hh24:mi:ss') from dual union all 
  select 3, '2013-2014', to_date('28.03.2015 11:20:47','DD.MM.YYYY hh24:mi:ss') from dual union all 
  select 1, '2014-2015', to_date('29.03.2015 12:20:47','DD.MM.YYYY hh24:mi:ss') from dual union all 
  select 2, '2014-2015', to_date('29.03.2015 12:20:47','DD.MM.YYYY hh24:mi:ss') from dual union all 
  select 3, '2014-2015', to_date('29.03.2015 12:20:47','DD.MM.YYYY hh24:mi:ss') from dual)
select * from (
  select 
     v1.*, 
     row_number() over (partition by ist order by entry_date desc) as rn
  from v_data v1
) 
where rn=1

此解决方案

  • 使用ROW_NUMBER分析函数
  • 计算每个组的排序
  • 使用WHERE rn = 1
  • 删除除了每个组的最新条目以外的所有内容

答案 1 :(得分:1)

您可以先对结果进行分组:

select ist, max(date) date
from   table
group
by     ist

然后,您可以将结果与select结合使用,以获得所有匹配的行:

select master.*
from   table master
join
( select ist, max(date) date
  from   table
  group
  by     ist
) filter
on     master.ist  = filter.ist
and    master.date = filter.date

答案 2 :(得分:0)

使用NOT EXISTS查找表中没有较新行的ist:

select *
from tablename t1
where not exists (select 1 from tablename t2
                  where t2.ist = t1.ist
                    and t2.date > t1.date)*
相关问题