不要忘记有数百种模式要匹配的要求。那么使用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
你重新写不等同于原来的。在原文中,如果'string1'或'string2'或**两个**都匹配,则在输出中会得到一行。在重写时,如果两个字符串都匹配,则会得到两行。这是期望的结果? – mathguy
理想情况下,我想要的结果是有columnX,和所有得到与特定columnX匹配的模式。 例如这样的结果对我来说很理想: ColumnX,pattern “value1”,“string1,string2” “value2”,“foo” –