我有一个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'和创建日期)。我在这里需要的是提取三组:
如果两个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 BY
和OVER
(分析函数)但他们似乎没有做到这一点。
有没有人遇到过这样的问题?你会如何解决它?
提前致谢。
答案 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值基。