postgresql:基于具有多个值的数组字段值搜索记录

时间:2018-07-06 17:35:29

标签: postgresql

我有一个带有数组字段的表。

CREATE TABLE notifications
(
    id integer NOT NULL DEFAULT nextval('notifications_id_seq'::regclass),
    title character(100) COLLATE pg_catalog."default" NOT NULL,
    tags text[] COLLATE pg_catalog."default",
    CONSTRAINT notifications_pkey PRIMARY KEY (id)
)

tags字段可以具有

中的多个值
["a","b","c","d"]

现在,我希望所有标记具有ad"a","d")数组值的记录。

我可以使用postgresl in,但这可以用于搜索单个值。我该如何实现?

2 个答案:

答案 0 :(得分:3)

您可以使用ANY

SELECT *
FROM notifications
WHERE 'a' = ANY(tags) OR 'b' = ANY(tags);

DBFiddle Demo

答案 1 :(得分:1)

如果值“ a”和“ b”是静态的(您只需在每个查询中检查这两个值),则可以采用Lukasz Szozda提供的解决方案。

但是,如果要检查的值是动态的,并且在多个查询中不同(有时为{'a','b'},但有时为{'b','f','m'} ),您可以创建两个数组的交集,并检查交集是否为空。

例如:

如果我们有以下表格和数据:

CREATE TABLE test_table_1(description TEXT, tags TEXT[]);
INSERT INTO test_table_1(description, tags) VALUES
  ('desc1', array['a','b','c']),
  ('desc2', array['c','d','e']);

如果我们要从test_table_1获取具有以下标记之一的所有行bfm,则可以使用以下查询:

SELECT * FROM test_table_1 tt1
 WHERE  array_length((SELECT array
    (
        SELECT UNNEST(tt1.tags)
        INTERSECT
        SELECT UNNEST(array['b','f','m'])
    )), 1) > 0;

在上面的查询中,我们使用array_length检查交叉点是否为空。

如果要向匹配的标签数量添加其他约束,以这种方式编写查询也很有用。 例如,如果要从组{'a','b','c'}中获取至少包含2个标签的所有行,则只需设置array_length(...) > 1