2016-12-07 57 views
0

我有一個名爲TVL_DETAIL的表,其中包含列TVL_CD_LIST。列TVL_CD_LIST包含三個記錄:
TVL_CD_LIST:
M1180_Z6827
K5900_Z6828
I2510在Oracle 10g中使用REGEXP_SUPSTR分析帶分隔符的值

我用下面的代碼,試圖只返回值(不包括這樣的下劃線):

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

要回答您的問題,您需要查詢與子元素相匹配的列表,並且只有列表由一個元素組成時纔會發生。你真正想要選擇的是子元素本身。

注:使用正則表達式形式'[^_]+'爲什麼解析字符串的解釋是壞在這裏: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> 

編輯:通過行和元件排內跟蹤哎呀,編輯按10g爲REGEXP_COUNT工作不可用直到11g。

+0

謝謝Gary_W ......所以當我運行查詢,我得到這個錯誤:ORA-00939:對於功能 – user3666552

+0

的參數太多仔細檢查你的語法,你可以看到它爲我工作。 –

0

您使用的查詢創建列表中,但你是比較使用的in條款列它自我記錄的名單,因爲這樣M1180Z6827不能等於M1180_Z6827等爲K5900_Z6828I2510只有一個值,因此得到匹配。

如果您的要求與您所期望的輸出中提到的完全相同,您可以使用下面的查詢。

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