【问题标题】:Oracle: "grep" across multiple columns?Oracle:跨多个列的“grep”?
【发布时间】:2010-01-29 09:36:40
【问题描述】:

我想跨多个列执行likeregexp。这些列包含标签、关键字等。相当于:

sqlplus scott/tiger @myquery.sql | grep somestring

现在我有类似的东西

select * from foo where c1 || c2 || c3  like '%somestring%'

但我希望我能得到一些更通用和/或优化的东西。任何线索表示赞赏!

【问题讨论】:

    标签: sql oracle grep


    【解决方案1】:

    您是否考虑过使用 Oracle Text 的级联数据存储功能?

    Oracle Text 允许您在同一个表中的多个列上创建全文索引。或者至少有一个过程可以做到这一点。

    在我之前使用过的 Oracle 网站上有一个很好的示例文档:

    http://www.oracle.com/technology/sample_code/products/text/htdocs/concatenated_text_datastore/cdstore_readme.html

    Oracle Text 搜索速度快得离谱。我想我会考虑在每个单独的列上保留单独的上下文索引,以便您可以将相关性和优先级应用于每个列匹配。

    如果您想要一个示例,请告诉我,我会在答案中添加一些内容。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      在 11G 上,您可以创建一个虚拟列:

      alter table foo add all_text varchar2(4000) generated always as (c1 ||','|| c2 ||','|| c3);
      

      (见Oracle 11G new features)。

      然后查询:

      select * from foo where all_text like '%somestring%'
      

      如果它也有助于提高性能,您可以在 all_text 上添加索引(请参阅this answer 了解何时可能有帮助,何时无用)。

      在 11G 之前,您可以做同样的事情,但使用普通列,通过触发器维护。

      【讨论】:

        【解决方案3】:

        作为一名顾问,我经常需要在文档记录不佳的数据库中进行搜索,并且需要一些方便的脚本来查找数据。下面是两个示例,如何生成用于在表中的所有 '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';
        

        【讨论】:

          【解决方案4】:

          regexp_like 有帮助吗?

          http://www.psoug.org/reference/regexp.html

          【讨论】:

            【解决方案5】:
            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>)
            

            这应该可以。但我怀疑这是否会比您的查询更好。您可能想比较两者的性能。真的很想听听你的发现。 :-)

            【讨论】:

              猜你喜欢
              • 2017-09-17
              • 2013-02-05
              • 1970-01-01
              • 2023-01-13
              • 2018-06-24
              • 2012-07-26
              • 2013-08-19
              • 1970-01-01
              • 2021-09-05
              相关资源
              最近更新 更多