2016-11-15 24 views
2

如果我有這樣的Oracle中的集合:ORACLE - 如何計算集合中成員的出現次數?

DECLARE 
    TYPE v_type IS TABLE OF varchar2(4000); 
    v_coll v_type := v_type(); 
    v_num_dups NUMBER; 
BEGIN 
    v_coll.extend(); 
    v_coll(1):= 'not dupe'; 
    v_coll.extend(); 
    v_coll(2):= 'dupe'; 
    v_coll.extend(); 
    v_coll(3):= 'dupe'; 

    for i in 1..v_coll.count loop 
     dbms_output.put_line(v_coll(i)); 
    end loop; 

END; 

我怎麼能返回dupe出現組成v_num_dups了計數,而通過收集和循環計數?

有沒有簡單的方法來說v_coll.count('dupe')或類似的東西?

回答

1

如果您想完全避免重複,可以使用關聯數組。喜歡的東西:

DECLARE 
    TYPE v_type IS TABLE OF number index by varchar2(4000); 
    v_coll v_type; 
    idx varchar2(4000); 
BEGIN 
    v_coll('not dupe'):= 1; 
    v_coll('dupe'):= 1; 
    v_coll('dupe'):= 1; 

    -- show key values 
    idx := v_coll.first; 
    loop 
     exit when idx is null; 
     dbms_output.put_line(idx); 
     idx := v_coll.next(idx); 
    end loop; 

END; 

輸出:

dupe 
not dupe 
+0

哇,這是偉大的...任何重複只會指向之前添加的最後一個值。如果你想*重複值,我猜它很糟糕,但如果不是,這真是太棒了!謝謝!!! –

0

不幸的是,沒有(至少11g)。 您必須手動遍歷集合並執行計數。

0

雖然我喜歡tbone的回答,這也工作得非常不錯,除去重複:

DECLARE 
    TYPE v_type IS TABLE OF varchar2(4000); 
    v_coll v_type := v_type(); 
    v_num_dups NUMBER; 
BEGIN 
    v_coll.extend(); 
    v_coll(1):= 'not dupe'; 
    v_coll.extend(); 
    v_coll(2):= 'dupe'; 
    v_coll.extend(); 
    v_coll(3):= 'dupe'; 

    v_coll:=SET(v_coll); --<----remove dups! 

    dbms_output.put_line(cardinality(v_coll)); 

    for i in 1..v_coll.count loop 
     dbms_output.put_line(v_coll(i)); 
    end loop; 

END; 
+1

它很好,但很大的卷很慢...... ;-)當你使用tbone建議的方法(我認爲是最好的方法)時,要注意空值。如果您將null指定爲密鑰,則循環將停止正常工作。 – Rusty