2014-08-29 51 views
0

我有一個PL/SQL嵌套表集合,其中包含以下元素:PL/SQL嵌套表圈

AG~AG~1~14 
US~BRANCH~1~24 
NO~NO~2~10 
KI~296~2~13 
AI~AI~2~21 

我看值在第三子元素與每個元素的(不知道如何把它!),並選擇具有最高價值的一個。 在上面的數據中,第3個子元素是1,1,2,2,2(緊接在第二個〜之後)。 顯然在這裏,包含2的元素更高。所以,其中3個符合標準。 此外,從其中的3個,我必須看第4個子元素,並最終選擇具有最高價值的元素。 所以,這3個元素的第4個子元素是:10,13,21 由於21是最高的,所以最終的輸出是挑選元素AI〜AI〜2〜21。

我正在努力如何以最好的方式做到這一點。 我嘗試了instr和substr的各種組合,並將它們組合起來進行比較。但是,它不夠模塊化。 我也可以標記每個元素的字符串並將其推入一個對會話有效的全局臨時表中,然後使用oracle sql獲取最終數據。但是,我想避免使用一個表並維護它,如果可能的話,就像保持在pl/sql中一樣。

declare 
TYPE final_score_typ IS TABLE OF varchar2(1000); 

l_final_score final_score_typ; 

l_final_output varchar2(20); 

begin 

<code logic that populates the nested table containing the above data> 

for j in 1..l_final_score.count loop 

    dbms_output.put_line(l_final_score(j)); 

end loop; 

dbms_output.put_line('final output string is:' || l_final_output); 


end; 

的最終輸出應被打印爲AI〜AI〜2〜21 任何指針將不勝感激。我可以基於他們至少嘗試......現在,想不出好的替代方案。

回答

1
select min(column_value) keep (dense_rank first order by 
    to_number(regexp_substr(column_value, '[^~]+', 1, 3)) desc, 
    to_number(regexp_substr(column_value, '[^~]+', 1, 4)) desc 
) 
into l_final_output 
from table(l_final_score) 

注:類型必須是全球性的:

create TYPE final_score_typ AS TABLE OF varchar2(1000); 
+0

謝謝。但是,如何在我的pl/sql塊中訪問這個全局集合類型來填充這些值?在我原來的文章中,我已經聲明瞭一個本地pl/sql嵌套表集合類型並填充了初始值。我按照您的名字final_score_typ的建議創建了一個全局類型。但是,在我的pl/sql塊中訪問它不起作用。我這樣聲明:l_final_score final_score_typ:= final_score_typ();它給我一個編譯錯誤:必須聲明「標識符final_score_typ」。感謝Egor – Casey 2014-08-30 05:29:37

+0

。有用。 – Casey 2014-08-31 17:35:40

+0

如果收集的數據可能會產生平局,則上述查詢不起作用,我不確定如何將所有這些平局數據作爲結果返回。值:final_score_typ('KI〜296〜1〜9','US〜CA〜2〜11','CA〜CA〜2〜11','KP〜KOREA〜2〜14','KR〜KOREA〜2 〜'','US〜CA〜3〜19','CA〜CA〜3〜19') 這裏'US_CA_3_19'和'CA_CA_3_19'都是有效的因爲他們的第三個子元素是最高的,他們的第四個是19的相同值,因此產生一個聯繫。在這裏,我的輸出應該是返回它們兩個。目前,上述查詢根據最小邏輯選取「CA〜CA〜3〜19」。 – Casey 2014-09-06 04:56:13

0

有您可以使用VARCHAR2的表中現有的數據庫類型(1000):'

SYS.DBMS_DEBUG_VC2COLL

你可以像這樣使用它:

declare 
    l_data SYS.DBMS_DEBUG_VC2COLL := SYS.DBMS_DEBUG_VC2COLL 
             ('AG~AG~1~14' 
             ,'US~BRANCH~1~24' 
             ,'NO~NO~2~10' 
             ,'KI~296~2~13' 
             ,'AI~AI~2~21' 
             ); 
    l_result varchar2(100); 
begin 
    select column_value 
    into l_result 
    from 
    (select column_value 
      , row_number() over 
       (order by substr(column_value 
           ,instr(column_value,'~',1,2)+1 
           ,instr(column_value,'~',1,3) 
            -instr(column_value,'~',1,2)-1 
           ) desc 
       ,   substr(column_value,instr(column_value,'~',1,3)+1) desc 
       ) as rn 
    from table (l_data) 
    ) where rn = 1; 
    dbms_output.put_line(l_result); 
end; 

(或者你可以使用它與Egor的更優雅的regexp_substr代碼當然。)

+0

謝謝託尼。我嘗試了兩種方法,他們的工作。 – Casey 2014-08-31 17:36:19