【发布时间】:2010-01-29 09:36:40
【问题描述】:
我想跨多个列执行like 或regexp。这些列包含标签、关键字等。相当于:
sqlplus scott/tiger @myquery.sql | grep somestring
现在我有类似的东西
select * from foo where c1 || c2 || c3 like '%somestring%'
但我希望我能得到一些更通用和/或优化的东西。任何线索表示赞赏!
【问题讨论】:
我想跨多个列执行like 或regexp。这些列包含标签、关键字等。相当于:
sqlplus scott/tiger @myquery.sql | grep somestring
现在我有类似的东西
select * from foo where c1 || c2 || c3 like '%somestring%'
但我希望我能得到一些更通用和/或优化的东西。任何线索表示赞赏!
【问题讨论】:
您是否考虑过使用 Oracle Text 的级联数据存储功能?
Oracle Text 允许您在同一个表中的多个列上创建全文索引。或者至少有一个过程可以做到这一点。
在我之前使用过的 Oracle 网站上有一个很好的示例文档:
Oracle Text 搜索速度快得离谱。我想我会考虑在每个单独的列上保留单独的上下文索引,以便您可以将相关性和优先级应用于每个列匹配。
如果您想要一个示例,请告诉我,我会在答案中添加一些内容。
希望这会有所帮助。
【讨论】:
在 11G 上,您可以创建一个虚拟列:
alter table foo add all_text varchar2(4000) generated always as (c1 ||','|| c2 ||','|| c3);
然后查询:
select * from foo where all_text like '%somestring%'
如果它也有助于提高性能,您可以在 all_text 上添加索引(请参阅this answer 了解何时可能有帮助,何时无用)。
在 11G 之前,您可以做同样的事情,但使用普通列,通过触发器维护。
【讨论】:
作为一名顾问,我经常需要在文档记录不佳的数据库中进行搜索,并且需要一些方便的脚本来查找数据。下面是两个示例,如何生成用于在表中的所有 'VARCHAR2' 列中搜索数据的选择子句:
示例 1。搜索部分字符串:
SELECT 'SELECT * FROM ' || min(TABLE_NAME) ||' WHERE ' || LISTAGG(COLUMN_NAME, ' like ''%somestring%'' or ') WITHIN GROUP (ORDER BY COLUMN_ID) || ' like ''%somestring%'';'
from ALL_TAB_COLUMNS
WHERE OWNER = 'YOUR_SCHEMA_NAME' -- Uppercase
AND TABLE_NAME = 'YOUR_TABLE_NAME' --Uppercase
AND DATA_TYPE LIKE 'VARCHAR2';
示例 2。搜索整个值:
SELECT 'SELECT * FROM ' || min(TABLE_NAME) ||' WHERE ''somestring'' in (' || LISTAGG(COLUMN_NAME, ', ') WITHIN GROUP (ORDER BY COLUMN_ID) || ');'
from ALL_TAB_COLUMNS
WHERE OWNER = 'YOUR_SCHEMA_NAME' -- Uppercase
AND TABLE_NAME = 'YOUR_TABLE_NAME' --Uppercase
AND DATA_TYPE LIKE 'VARCHAR2';
【讨论】:
regexp_like 有帮助吗?
【讨论】:
SELECT * FROM table WHERE REGEXP_LIKE(col1, <pattern>)
union
SELECT * FROM table WHERE REGEXP_LIKE(col2, <pattern>)
union
SELECT * FROM table WHERE REGEXP_LIKE(col3, <pattern>)
这应该可以。但我怀疑这是否会比您的查询更好。您可能想比较两者的性能。真的很想听听你的发现。 :-)
【讨论】: