2016-12-07 40 views
0

私は、TVL_DETAILというテーブルにTVL_CD_LIST列が含まれています。
TVL_CD_LIST:
M1180_Z6827
K5900_Z6828
I2510Oracle 10gでREGEXP_SUPSTRを使用して区切り値を解析する

私は(そうアンダースコアを除く)のみの値を返すための試みで、次のコードを使用しました:

列TVL_CD_LISTは、3つのレコードが含まれています
SELECT 
TVL_CD_LIST 
FROM TVL_DETAIL 
WHERE TVL_CD_LIST IN (SELECT regexp_substr(TVL_CD_LIST,'[^_]+', 1, level) FROM DUAL 
CONNECT BY regexp_substr(TVL_CD_LIST,'[^_]+', 1, level) IS NOT NULL) 

別の行に返されると予想されたのは、
M1180
Z6827
K5900
Z6828
I2510

それだけ(下線を含まない元の値である)I2510を返します。

私は間違っていますか?どんな助けもありがとうございます。ありがとう!

答えて

0

質問に答えるには、サブ要素と一致するリストをクエリしています。リストは1つの要素で構成されている場合にのみ発生します。あなたが本当に選択したかったのは、サブ要素そのものです。

注:正規表現の形式'[^_]+'を使用して文字列を解析すると、ここで悪い理由の説明:https://stackoverflow.com/a/31464699/2543416

あなたは要素を選択し、リストを解析したい:

SQL> with TVL_DETAIL(TVL_CD_LIST) as (
    select 'M1180_Z6827' from dual union 
    select 'K5900_Z6828' from dual union 
    select 'I2510' from dual 
    ) 
    SELECT distinct regexp_substr(TVL_CD_LIST, '(.*?)(_|$)', 1, level, NULL, 1) element 
    FROM TVL_DETAIL 
    CONNECT BY level <= LENGTH(regexp_replace(TVL_CD_LIST, '[^_]', '')) + 1; 
    -- 11g CONNECT BY level <= regexp_count(TVL_CD_LIST, '_') + 1; 

ELEMENT 
----------- 
Z6827 
K5900 
M1180 
I2510 
Z6828 

SQL> 

そして、あなたがしたい場合、これはクールです

SQL> with TVL_DETAIL(row_nbr, TVL_CD_LIST) as (
    select 1, 'M1180_Z6827' from dual union 
    select 2, 'K5900_Z6828' from dual union 
    select 3, 'I2510' from dual 
    ) 
    SELECT row_nbr, column_value substring_nbr, 
      regexp_substr(TVL_CD_LIST, '(.*?)(_|$)', 1, column_value, NULL, 1) element 
    FROM TVL_DETAIL, 
    TABLE(
     CAST(
     MULTISET(SELECT LEVEL 
        FROM dual 
        CONNECT BY level <= LENGTH(regexp_replace(TVL_CD_LIST, '[^_]', '')) + 1 
        -- 11g CONNECT BY LEVEL <= REGEXP_COUNT(TVL_CD_LIST, '_')+1 
       ) AS sys.OdciNumberList 
      ) 
    ) 
    order by row_nbr, substring_nbr; 

    ROW_NBR SUBSTRING_NBR ELEMENT 
---------- ------------- ----------- 
     1    1 M1180 
     1    2 Z6827 
     2    1 K5900 
     2    2 Z6828 
     3    1 I2510 

SQL> 

EDIT:行内の行及び要素によって追跡するおっと、REGEXP_COUNTとして10gに動作するように編集が使用できません11gまで。

+0

おかげでGary_Wは...そう、私は得るこのエラー:ORA-00939:機能 – user3666552

+0

のためにあまりにも多くの引数を使って、慎重にあなたの構文をチェックそれは私のために働いて見ることができます。 –

0

あなたが使用しているクエリは、リストを作成しますが、このようなM1180Z6827K5900_Z6828ためM1180_Z6827などに等しくすることができないとして、あなたは、in句を使用して、カラム、それを自己を持つレコードのリストを比較しています。 I2510には値が1つしかないため、一致します。

ご希望の出力に記載されている要件とまったく同じ場合は、以下のクエリを使用できます。

SQL> WITH tvl_detail AS 
     2 (SELECT 'M1180_Z6827' tvl_cd_list FROM dual 
     3 UNION ALL 
     4 SELECT 'K5900_Z6828' FROM dual 
     5 UNION ALL 
     6 SELECT 'I2510' FROM dual) 
     7 --------------------------- 
     8 --- End of data preparation 
     9 --------------------------- 
    10 SELECT regexp_substr(tvl_cd_list, '[^_]+', 1, LEVEL) AS tvl_cd_list 
    11 FROM tvl_detail 
    12 CONNECT BY regexp_substr(tvl_cd_list, '[^_]+', 1, LEVEL) IS NOT NULL 
    13   AND PRIOR tvl_cd_list = tvl_cd_list 
    14   AND PRIOR sys_guid() IS NOT NULL; 

OUTPUT:私は、クエリを実行すると

TVL_CD_LIST 
-------------------------------------------- 
I2510 
K5900 
Z6828 
M1180 
Z6827 
関連する問題