如何:Oracle 解析函数返回行

Posted

技术标签:

【中文标题】如何:Oracle 解析函数返回行【英文标题】:How to: Oracle analytic function to return row 【发布时间】:2021-01-27 13:51:37 【问题描述】:

我想我的问题可以用一个回答 Oracle 解析函数中的 SQL 但我不是 确定。 假设我有以下“文档”数据库表:

排名:逆序,每个文档都有自己的顺序,最新文档修订号最低(0) 修订:每个文档的字母数字序列,最新文档修订具有最高修订 ID
NAME RANK REVISION STATE
DocumentA 0 5b ReadOnly
DocumentA 1 5a Draft
DocumentA 3 3 ReadOnly
DocumentA 4 2 Draft
DocumentA 2 4 Published
DocumentA 5 1 Published
DocumentB 0 2 Draft
DocumentB 1 1 Published
DocumentC 0 1 Published

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

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

由于最新的文档修订可能处于状态草稿中,因此并不总是 0

NAME RANK REVISION STATE
DocumentA 2 4 Published
DocumentB 1 1 Published
DocumentC 0 1 Published

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

【问题讨论】:

dba.stackexchange.com/questions/6368/… 无论何时从最早的行开始按降序排列,您是否想获得Draft 之前的倒数第二行? 我只对已发布的修订感兴趣,无论之前或之后添加了多少文档修订 您决定 DocumentA RANK 2 REVISION 4,因为 RANK 2 REVISION 1? 因为排名 2 【参考方案1】:

这样的?

SQL> with test (name, rank, revision, state) as
  2    (select 'A', 0, '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', 0,  '2', 'Draft'     from dual union all
  6     select 'B', 1,  '1', 'Published' from dual union all
  7     select 'C', 0,  '1', 'Published' from dual
  8     )
  9  select name, rank, revision, 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>

【讨论】:

【参考方案2】:

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

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

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;

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

【讨论】:

以上是关于如何:Oracle 解析函数返回行的主要内容,如果未能解决你的问题,请参考以下文章

如何从函数游标返回行并在oracle中循环

如何在Oracle中仅将列用作1行到1行返回pl / sql函数中的参数

如何从从 plsql 函数 ORACLE 返回的游标中进行选择

Oracle高级查询

perl函数操作符解析

如何使用 SELECT 从 Oracle 存储过程中返回行?