Oracle在每个新值上“分区”一个表

时间:2015-07-21 11:00:31

标签: oracle oracle11g

我有一个Oracle表我需要“分区”:我松散地使用terme,我只需要检测组并希望通过SELECT显示该组。这是一个可以作为样本数据的示例(四列):

ID | Ref | Rank | Partition_group (only available for the 1st member)
1  | 1   | 1    | 1_A
2  | 1   | 2    | (null)
3  | 1   | 3    | 1_B
4  | 2   | 1    | (null)
5  | 2   | 2    | 2_A
...

它是排序的(排序键是'Ref'和创建日期)。我在这里需要的是提取三组:

  • ID 1和2
  • ID 3
  • ID 5 ID 4发生的事情并不重要:它可能在自己的组中,也可能在ID 5中。

如果两个IDS具有相同的“Ref”并且没有任何“Partition_group”更改,则它们应该在同一个组中。换句话说,每次更改'Ref'或(逻辑或)'Partition_group'时,我都需要检测一个新组。例如,我们可以返回类似的内容:

ID | Ref | Rank | Partition_group | Group
1  | 1   | 1    | 1_A             | 1_A
2  | 1   | 2    | (null)          | 1_A
3  | 1   | 3    | 1_B             | 1_B
4  | 2   | 1    | (null)          | (null) (or 2_A)
5  | 2   | 2    | 2_A             | 2_A
...

我考虑过编写一个函数或者其他东西,但似乎我没有这样做的权利(是的......)所以我必须使用普通的Oracle SQL(11g)。 我一直在关注CONNECT BYOVER(分析函数)但他们似乎没有做到这一点。

有没有人遇到过这样的问题?你会如何解决它?

提前致谢。

1 个答案:

答案 0 :(得分:0)

假设输入数据是前四列,那么如下:

with sample_data as (select 1 id, 1 ref, 1 rank, '1_A' ptn_group from dual union all
                     select 2 id, 1 ref, 2 rank, null ptn_group from dual union all
                     select 3 id, 1 ref, 3 rank, '1_B' ptn_group from dual union all
                     select 4 id, 2 ref, 1 rank, null ptn_group from dual union all
                     select 5 id, 2 ref, 2 rank, '2_A' ptn_group from dual)
select id,
       ref,
       rank,
       ptn_group,
       last_value(ptn_group ignore nulls) over (partition by ref order by rank, id) grp1,
       case when last_value(ptn_group ignore nulls) over (partition by ref order by rank, id) is null then
                 first_value(ptn_group ignore nulls) over (partition by ref order by rank, id rows between current row and unbounded following)
            else last_value(ptn_group ignore nulls) over (partition by ref order by rank, id)
       end grp2
from   sample_data;

        ID        REF       RANK PTN_GROUP GRP1 GRP2
---------- ---------- ---------- --------- ---- ----
         1          1          1 1_A       1_A  1_A 
         2          1          2           1_A  1_A 
         3          1          3 1_B       1_B  1_B 
         4          2          1                2_A 
         5          2          2 2_A       2_A  2_A 

根据您想要处理ptn_group的第一行为空的行的方式,我给出了两个生成grp的选项 - 将它们保留为null或者获取第一个非null值基。