以下是我的示例数据1
CP | NP |MC |DS |NNP
--- ---- --- -- ---
A | B | | |C
C | D | XX|YY |E
E | F | ZZ|11 |
预期输出 1
NP |MC |DS
--- ---- ---
B | ZZ|11
这里的“CP”和“NNP”列是分层的(即) 我们将从如下查询开始,针对特定的 NP,然后使用以下逻辑获取相应的 MC 和 DS 值
select MC, DS from tabl1
where NP=B
以下是我的示例数据2
CP | NP |MC |DS |NNP
--- ---- --- -- ---
A | B | 96|KK |C
C | D | XX|YY |E
E | F | ZZ|11 |
预期输出2(如果对应的根值不为空,那么我们也需要获取这些值
NP |MC |DS
--- ---- ---
B | 96|KK
B | ZZ|11
答案 0 :(得分:1)
直接应用分层(connect by
)查询:
select connect_by_root(np) as np, mc, ds
from sample_data
where connect_by_isleaf = 1 -- OR: nnp is null (IF NEEDED, SEE BELOW)
start with cp = 'A'
connect by cp = prior nnp
;
在您的输出中,在列 NP
中有值 B
,它是“根”行(起始行)中的值。您可以在此处使用 connect_by_root
。所有其他值都来自叶行(层次结构中的“最后”行)。这是我们需要使用过滤器 connect_by_isleaf = 1
的地方 - 非叶行(至少有一个子行)的值为 0,叶行的值为 1。
请注意,“叶子”意味着没有更多的孩子。如果 NNP
是 null
或它不是 null
但在 CP
列中找不到该值,都可能发生这种情况。如果您只需要 NNP
为 null
的叶行,您可以更改 where
子句,如上面的代码所示。
EDIT OP 请求修改 - 除了 leaf 之外,输出还应包括 root 行,但前提是mc
或 ds
值(或两者)是/不是 null
。这可以通过更改 where
子句来实现,它应该是:
...
where (connect_by_isleaf = 1)
or (level = 1 and (mc is not null or ds is not null))
...
答案 1 :(得分:0)
您可以使用递归 CTE。例如:
with
n (cp, np, mc, ds, nnp, lvl) as (
select cp, np, mc, ds, nnp, 1 from t where cp not in (
select nnp from t where nnp is not null
)
union all
select n.cp, n.np, n.mc, n.ds, t.nnp, n.lvl + 1
from n
join t on t.cp = n.nnp
),
m as (select np, max(lvl) as max_lvl from n group by np)
select m.np, n.mc, n.ds
from n
join m on m.np = n.np and m.max_lvl = n.lvl
我没有测试这个查询的语法问题,但策略是正确的。