2017-07-07 34 views
0

時顯示的結果,而得到的結果的參數我有一個查詢select查詢使用,或者在(甲骨文)子句

select columnX from tableA 
    where (columnY like '%string1%' or columnY like '%string2%'); 

,但我也想知道得到了所匹配的參數(字符串1或字符串2)因爲它的我得到了我的結果,所以我修改我的查詢到

select columnX value,'string1' pattern from tableA 
    where columnY like '%string1%' 
    union 
    select columnX,'string2' from tableA 
    where columnY like '%string2%' 

這給了我,我的結果,但使查詢巨大的(因爲我有去匹配所以基本上數以百計的模式我寫整個查詢每個參數),我非常懷疑這是做這件事的最好方法,是否有一些ot她的方式來做到這一點,我不必爲我想匹配的所有模式寫一個新的查詢? 這可以通過簡單地修改查詢或我將不得不使用Oracle SQL的任何先進的結構進行什麼,我需要做什麼?

+1

你重新寫不等同於原來的。在原文中,如果'string1'或'string2'或**兩個**都匹配,則在輸出中會得到一行。在重寫時,如果兩個字符串都匹配,則會得到兩行。這是期望的結果? – mathguy

+0

理想情況下,我想要的結果是有columnX,和所有得到與特定columnX匹配的模式。 例如這樣的結果對我來說很理想: ColumnX,pattern 「value1」,「string1,string2」 「value2」,「foo」 –

回答

3

不要忘記有數百種模式要匹配的要求。那麼使用case語句的解決方案是不切實際的,恐怕你不得不編輯數百個這樣的解決方案。將比較字符串放在一個表中。在這裏我通過使用CTE(compare_strings表)來模擬。如果你需要添加一個值來比較,你只需將其添加到compare_strings表和查詢沒有改變。要模擬,將'efs'編輯爲'blah',然後您將拾取第1行。

儘管如此,根據您的示例,比較字符串將匹配它出現在columnY中的任何位置,即使字符串嵌入在另一個單詞中,而這個單詞可能不是您想要匹配的單詞。爲了得到更精確,你可能需要切換到使用REGEXP_LIKE在那裏你可以定製正則表達式來滿足您的需求。

SQL> WITH tableA(columnX, columnY) AS (
    SELECT 1, 'blah blah blah' FROM DUAL UNION 
    SELECT 2, 'string2'   FROM DUAL UNION 
    SELECT 3, 'string'   FROM DUAL UNION 
    SELECT 4, 'string1'   FROM DUAL UNION 
    SELECT 5, 'string1 string2' FROM DUAL UNION 
    SELECT 6, NULL    FROM DUAL UNION 
    SELECT 7, 'string3'   FROM DUAL 
    ), 
    COMPARE_STRINGS(description) AS (
    SELECT 'string1' FROM DUAL UNION 
    SELECT 'efs'  FROM DUAL UNION 
    SELECT 'string2' FROM DUAL UNION 
    SELECT 'Mata Hairy' FROM DUAL UNION 
    SELECT 'string3' FROM DUAL 
    ) 
    SELECT columnX, cs.description "hit string" 
    FROM TABLEA A CROSS JOIN COMPARE_STRINGS CS 
    WHERE a.columnY LIKE '%' || cs.description || '%' 
    ORDER BY columnX; 

    COLUMNX hit string 
---------- ---------- 
     2 string2 
     4 string1 
     5 string1 
     5 string2 
     7 string3 

請注意,您會在第5行中獲得2個匹配,因爲columnY包含compare_strings表中的2個條目。你需要決定你想如何處理。看到上面的警告。

編輯17年7月10日把每行多重命中串在一行。

改變查詢使用LISTAGG():

SELECT columnX, 
    LISTAGG(cs.description, '|') WITHIN GROUP (ORDER BY columnX) hit_string 
    FROM TABLEA A CROSS JOIN COMPARE_STRINGS CS 
    WHERE a.columnY LIKE '%' || cs.description || '%' 
    GROUP BY columnX; 

SQL>/

    COLUMNX HIT_STRING 
---------- -------------------- 
     2 string2 
     4 string1 
     5 string1|string2 
     7 string3 
+0

非常感謝,這正是我所尋找的解決方案。 有沒有一種方法可以修改它,使單列中的列中的所有命中字符串都被一些分隔符分開? –

+0

更新後顯示LISTAGG如何實現此目的。我將它保存在我的SQL技巧文件夾中。 –

0

你可以與邏輯返回一個新列:

CASE WHEN columnY like '%string1%' THEN 'string1' 
     WHEN columnY like '%string2%' THEN 'string2' 
    END 
0
SELECT columnX, 
CASE 
    WHEN columnY like '%string1%' THEN 'string1' 
    WHEN columnY like '%string2%' THEN 'string2' 
    ELSE NULL 
END AS pattern 
FROM tableA 
WHERE (columnY like '%string1%' or columnY like '%string2%'); 

編輯:您還可以使用ISNULL('string1','value you want')如果「字符串1」和「字符串2」的值可能爲空

0
with tableA as(
    select 'asd' columnY from dual union all 
    select 'string2' columnY from dual union all 
    select 'string' columnY from dual union all 
    select 'string1' columnY from dual union all 
    select 'string1 string2' columnY from dual 
) 

select * from (
    select tableA.*, 
    case when columnY like '%string1%' then 1 else 0 end+ 
    case when columnY like '%string2%' then 2 else 0 end as res 
    from tableA 
) t 
where res > 0 

如果res列是1,意味着columnY僅包含「字符串1」,如果res是2,這意味着,僅包含「字符串2」,並且如果res爲3,則columnY包含'string1'和'string2'