如何:Oracle 分析函数返回行

问题描述

我想我的问题可以用 sql中的oracle解析函数但是我不是 确定。 假设我有以下“DOCUMENTS”数据库表:

  • Rank:Reverse Sequence,每个文档都有自己的顺序,最新的文档修订版本最低(0)
  • Revision:每个文档的 Alpha 数字序列,最新的文档修订版具有最高修订版 id
NAME RANK 修订 STATE
DocumentA 0 5b 只读
DocumentA 1 5a 草稿
DocumentA 3 3 只读
DocumentA 4 2 草稿
DocumentA 2 4 已发布
DocumentA 5 1 已发布
DocumentB 0 2 草稿
DocumentB 1 1 已发布
DocumentC 0 1 已发布

请求的结果集:每个文档的最新发布修订

给我,对于每个文档,最新发布的文档,排名最低的文档

由于最新的文档修订版可以在状态草案中,因此并不总是 0

NAME RANK 修订 STATE
DocumentA 2 4 已发布
DocumentB 1 1 已发布
DocumentC 0 1 已发布

请制定 sql 查询以返回此结果集。非常感谢!

解决方法

类似的东西?

SQL> with test (name,rank,revision,state) as
  2    (select 'A','5b','ReadOnly'  from dual union all
  3     select 'A',2,'4','Published' from dual union all
  4     select 'A',5,'1','Published' from dual union all
  5     select 'B','2','Draft'     from dual union all
  6     select 'B',1,'Published' from dual union all
  7     select 'C','Published' from dual
  8     )
  9  select name,state
 10  from (select t.*,11          rank() over (partition by name order by revision desc,rank) rn
 12        from test t
 13        where state = 'Published'
 14       )
 15  where rn = 1;

N       RANK RE STATE
- ---------- -- ---------
A          2 4  Published
B          1 1  Published
C          0 1  Published

SQL>
,

请求的结果集:每个文档的最新发布修订

一种方法不使用窗口函数:

select t.*
from t
where t.state = 'Published' and
      t.rank = (select min(t2.rank) 
                from t t2
                where t2.name = t.name and t2.state = t.state
               );

而且,在 Oracle 中,您甚至可以使用聚合:

select document,state,min(rank),min(revision) keep (dense_rank first order by rank) as revision
from t
where state = 'Published'
group by document,state;

窗口函数是该问题的一个非常合理的解决方案,但是,它们不是必需的。