【问题标题】:PostgreSQL: Check if each item in array is contained by a larger stringPostgreSQL:检查数组中的每个项目是否包含在更大的字符串中
【发布时间】:2015-11-04 17:25:54
【问题描述】:

我在 PostgreSQL 中有一个字符串数组:

SELECT ARRAY['dog', 'cat', 'mouse'];

还有一大段:

Dogs and cats have a range of interactions. The natural instincts of each species lead towards antagonistic interactions, though individual animals can have non-aggressive relationships with each other, particularly under conditions where humans have socialized non-aggressive behaviors.

The generally aggressive interactions between the species have been noted in cultural expressions.

对于数组中的每个项目,我想检查它是否出现在我的大段落字符串中。我知道对于任何一个字符串,我都可以执行以下操作:

SELECT paragraph_text ILIKE '%dog%';

但是有没有一种方法可以同时检查数组中的每个字符串(对于任意数量的数组元素)而不使用 plpgsql?

【问题讨论】:

    标签: sql arrays postgresql sql-like


    【解决方案1】:

    我相信你想要这样的东西(假设 paragraph_text 是名为 table 的表中的列):

    SELECT
        paragraph_text,
        sub.word,
        paragraph_text ILIKE '%' || sub.word || '%' as is_word_in_text
    FROM
        table1 CROSS JOIN (
            SELECT unnest(ARRAY['dog', 'cat', 'mouse']) as word
        ) as sub;
    

    函数unnest(array) 根据数组值创建记录表。您可以执行CROSS JOIN,这意味着来自table1 的所有行都与来自该未嵌套表的所有行相结合。

    如果paragraph_text 是某种静态值(不是来自表格),您可以这样做:

    SELECT
        paragraph_text,
        sub.word,
        paragraph_text ILIKE '%' || sub.word || '%' as is_word_in_text
    FROM (
             SELECT unnest(ARRAY['dog', 'cat', 'mouse']) as word
         ) as sub;
    

    【讨论】:

    • 谢谢--CROSS JOIN 是个好主意。
    【解决方案2】:

    此解决方案仅适用于 postgres 8.4 及更高版本,因为 unrest 不适用于早期版本。

    drop table if exists t;
    create temp table t (col1 text, search_terms text[] );
    insert into t values
       ('postgress is awesome', array['postgres', 'is', 'bad']), 
       ('i like open source', array['open', 'code', 'i']), 
       ('sql is easy', array['mysql']);
    
    drop table if exists t1;
    select *, unnest(search_terms) as search_term into temp t1 from t;
    
    -- depending on how you like to do pattern matching. 
    -- it will look for term not whole words
    select *, position(search_term in col1) from t1;
    
    
    -- This will match only whole words.
    select *, string_to_array(col1, E' ')@>string_to_array(search_term, E' ') from t1;
    

    基本上,您需要将 search_terms 数组展平为一列,然后将长字符串与每个搜索词逐行匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-10
      • 2013-08-16
      • 2020-06-06
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      相关资源
      最近更新 更多