Postgres将数组中的每个元素与通配符进行比较

时间:2018-11-16 20:25:03

标签: arrays postgresql

我在postgres中有一个数组,我试图使用通配符比较各个元素。以下是我的追求。

 SELECT '{abcdefg,hijklmnop}'::TEXT[] ILIKE '{%cde%}'::TEXT[];       --> TRUE
 SELECT '{abcdefg,hijklmnop}'::TEXT[] ILIKE '{%cde%,%foo%}'::TEXT[]; --> FALSE
 SELECT '{abcdefg,hijklmnop}'::TEXT[] ILIKE '{%cde%,%mno%}'::TEXT[]; --> TRUE

1 个答案:

答案 0 :(得分:1)

有效地,您正在检查第二个数组中的所有模式是否与第一个数组中的ANY项目匹配。

很容易检查模式数组(SELECT EVERY(u ILIKE ANY('{%pattern%}')) FROM UNNEST('{values}') AS u)中第一个数组中的所有项是否都匹配,要少一些,因此如果存在不匹配有效的情况(例如,第一种情况) ,其中数组1中的项目2不匹配,但返回TRUE)。

我唯一想到的方法是将第一个数组中的每个项目与每个单独的模式进行比较,并说每个模式上至少必须有一个匹配项。

这很丑陋,但是可以给出正确的结果。 (您始终可以将其包装在函数中。)

SELECT EVERY(match)
FROM (
    SELECT BOOL_OR(value ILIKE pattern) AS match
    FROM UNNEST('{%cde%,%mno%}'::TEXT[]) AS pattern
    JOIN UNNEST('{abcdefg,hijklmnop}'::TEXT[]) AS value
        ON TRUE
    GROUP BY pattern
) AS matches

因此,首先取消嵌套数组,以便分别将每个值与每个模式进行比较。 (我相信您可以通过value ILIKE ANY('{your patterns}')将值与模式数组进行比较,但是如果不取消嵌套,则无法将值数组与模式进行比较。)

它执行BOOL_OR并按模式分组,因此每个模式得到一个结果;结果是:此模式的值是否匹配?

然后,外部查询会执行EVERY(与BOOL_AND相同)来检查每个结果是否为真(即每个模式都已匹配);如果是,则返回TRUE,否则返回FALSE。