PostgreSQL LIKE 对 ARRAY 字段的查询

Chr*_*itt 13 postgresql database-design pattern-matching

有没有办法LIKE在 ARRAY 字段上进行Postgres查询?

目前我想要这样的东西:

SELECT * FROM list WHERE lower(array_field) LIKE '1234%'
Run Code Online (Sandbox Code Playgroud)

目前不需要那么多。但是它应该在 ARRAY 中找到一个匹配的字段。这甚至可能吗?

目前我使用物化视图来生成带有 JOIN 和 a 的“列表”表ARRAY_AGG(),因为我加入了一个表,其中更多的值可能在正确的表上。这会重复左表中的字段,这不是我想要的。

编辑这就是我创建视图的方式(非常缓慢和丑陋):

CREATE MATERIALIZED VIEW article_list_new AS
SELECT a.id, 
       a.oa_nr, 
       a.date_deleted, 
       a.lock, 
       a.sds_nr, 
       a.kd_art_nr, 
       a.kd_art_index, 
       a.kd_art_extend, 
       a.surface, 
       a.execution, 
       a.surface_area, 
       a.cu_thickness, 
       a.endintensity, 
       a.drilling, 
       array_agg(o.id::text) AS offer_list 
FROM article_list a LEFT JOIN task_offer o ON o.article = a.oa_nr 
GROUP BY .....;  
Run Code Online (Sandbox Code Playgroud)

我还需要返回task_offer表的 ID 。

Erw*_*ter 15

您可以使用unnest()已经提到的@dezso,例如使用LATERAL连接(Postgres 9.3+)

SELECT l.*
FROM   list l, unnest(array_field) a  -- implicit lateral
WHERE  lower(a) LIKE '1234%';
Run Code Online (Sandbox Code Playgroud)

对于呈现的案例,您不需要任何这些。根本没有物化视图。这个对底层表的查询更快,因为它可以使用索引:

SELECT *  -- or selected columns
FROM   article_list a
JOIN   LATERAL  (                      -- only matching IDs
   SELECT array_agg(id) AS offer_list
   FROM   task_offer
   WHERE  article = a.oa_nr            -- LATERAL reference  
   AND    id::text ILIKE '1234%'       -- or just LIKE
   ) o ON offer_list IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)

offer_list是我的结果中原始数据类型的数组,并且包含匹配的 ID。

从 中返回具有article_list匹配 ID 数组的单行task_offer。添加text_pattern_ops索引(用于左锚匹配)以获得最佳读取性能:

CREATE INDEX task_offer_foo_idx ON task_offer (article, (id::text) text_pattern_ops);
Run Code Online (Sandbox Code Playgroud)

或中缀匹配的三元索引(非左锚定):

或者可能是选择性模式的简单连接:

SELECT a.*, o.offer_list -- or selected columns
FROM   article_list a
JOIN   (                          -- only matching IDs
   SELECT article, array_agg(id) AS offer_list
   FROM   task_offer
   WHERE  id::text ILIKE '1234%'  -- or just LIKE
   GROUP  BY 1
   ) o ON o.article = a.oa_nr;
Run Code Online (Sandbox Code Playgroud)

也需要一个索引article_list。(您可能拥有 - 问题中没有信息。)例如:

CREATE INDEX article_list_oa_nr_idx ON article_list (oa_nr);
Run Code Online (Sandbox Code Playgroud)