0

我需要在其层次结构下仅设置一组标志来识别主通道(层次结构中最高的)。在以下情况下,US 不是有效的主要渠道,因为下面有两个标志。只有 US1、US2、UK 才是有效的主要频道。

如果可能的话,我想有一个单一查询的解决方案;否则我将探索程序选项。

我尝试了分层查询、分组依据、计数(标志)的一些变体,不知何故我无法消除“美国”并获得所需的结果。

如果有人可以为这个用例提供高级方法,我将不胜感激。

输入数据

---------------------------------
channel | flag  | parent channel
---------------------------------
US      |       |               

US1     |       | US        
A1      | yes   | US1       
A2      |       | A1        
A3      |       | A2

US2     |       | US        
B1      |       | US2       
B2      | yes   | B1        
B3      |       | B2        

UK      |       |   
C1      |       | UK        
C2      |       | C1        
C3      | yes   | C2        
---------------------------------

使用输入数据的带有标志计数的多个层次结构

---------------------
channel | flag count 
---------------------
US      | 2     

US1     | 1     
A1      | 1 
A2      | 0      
A3      | 0      

US2     | 1     
B1      | 1      
B2      | 1   
B3      | 0      

UK      | 1      
C1      | 1      
C2      | 1      
C3      | 1   
----------------

输出

---------------------------------
primary channel
---------------------------------
US1
US2
UK
---------------------------------
4

1 回答 1

1

这有点棘手......当然,除非我错过了一个明显的捷径......

select max(channel) keep (dense_rank last order by lvl) as primary_channel
from (
  select channel, connect_by_root(channel) as root, level lvl,
    count(*) over (partition by channel) as flag_count
  from input_data
  connect by channel = prior parent_channel
  start with flag = 'yes'
)
where flag_count = 1
group by root;

PRIMARY_CHANNEL
---------------
US1
US2
UK

db<>小提琴演示。

内部查询是一个相当简单的分层查询,从三行向上遍历树,除了它还对每个在生成的层次结构中出现flag = 'yes'的次数进行分析计数。channel

select channel, connect_by_root(channel) as root, level lvl,
  count(*) over (partition by channel) as flag_count
from input_data
connect by channel = prior parent_channel
start with flag = 'yes';

CHANNEL ROOT        LVL FLAG_COUNT
------- ---- ---------- ----------
A1      A1            1          1
B1      B2            2          1
B2      B2            1          1
C1      C3            3          1
C2      C3            2          1
C3      C3            1          1
UK      C3            4          1
US      A1            3          2
US      B2            4          2
US1     A1            2          1
US2     B2            3          1

11 rows selected. 

然后,外部查询会消除计数大于 1 的任何位置 - 即两US行;并使用另一个分析函数为结果中剩余的每个根找到具有最高级别的行。


我假设US实际上只出现在你的input_data; 但如果它存在两次,那么它仍然有效,中间计数只是 4 而不是 2。你可以在这个 db<>fiddle中看到那个版本。

于 2018-07-18T18:06:29.497 回答