我有一个查询
select columnX from tableA
where (columnY like '%string1%' or columnY like '%string2%');
但我也想知道哪个参数(string1或string2)匹配,因为我得到了我的结果,所以我将查询修改为
select columnX value,'string1' pattern from tableA
where columnY like '%string1%'
union
select columnX,'string2' from tableA
where columnY like '%string2%'
这给了我我的结果,但是使查询变得很大(因为我有数百个模式要匹配,所以基本上我为每个参数编写了整个查询),我高度怀疑这将是最好的方法来做到这一点,是吗其他一些方法,我不必为我想要匹配的所有模式编写新查询? 这可以通过简单地修改查询来完成,还是必须使用Oracle SQL的任何高级构造来执行我需要的工作?
答案 0 :(得分: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个条目。您需要决定如何处理它。请参阅上面的警告。
编辑7/10/17在一行中每行放置多个命中字符串。
更改查询以使用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
答案 1 :(得分:0)
您可以使用该逻辑返回一个新列:
CASE WHEN columnY like '%string1%' THEN 'string1'
WHEN columnY like '%string2%' THEN 'string2'
END
答案 2 :(得分: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%');
修改:如果' string1'的值,您还可以使用ISNULL('string1','value you want')
和' string2'可能是null
答案 3 :(得分: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
仅包含'string1',如果res
为2,则表示仅包含'string2',如果{{1} }是3,然后res
包含'string1'和'string2'