【问题标题】:How to query all rows where a given column matches at least all the values in a given array with PostgreSQL?如何使用PostgreSQL查询给定列至少匹配给定数组中所有值的所有行?
【发布时间】:2021-02-22 13:34:23
【问题描述】:

下面的请求:

SELECT foos.id,bars.name
FROM foos
JOIN bar_foo ON (bar_foo.foo_id = id )
JOIN bars ON (bars.id = bar_foo.bar_id )

返回一个这样的列表:

id | name
---+-----
 1 | a
 1 | b
 2 | a
 2 | y
 2 | z
 3 | a
 3 | b
 3 | c
 3 | d

如何获取id 必须至少有ab 的id,更一般地说是给定数组的内容?

从上面的例子中,我会得到:

id | name
---+-----
 1 | a
 1 | b
 3 | a
 3 | b
 3 | c
 3 | d

【问题讨论】:

    标签: sql arrays postgresql where-clause relational-division


    【解决方案1】:

    对于两个值,可以使用加窗布尔聚合:

    select *
    from (
        select f.id, b.name, 
            bool_or(b.name = 'a') over(partition by id) has_a,
            bool_or(b.name = 'b') over(partition by id) has_b
        from foos f
        join bar_foo bf on bf.foo_id = f.id
        join bars b on b.id = bf.bar_id
    ) t
    where has_a and has_b
    

    更通用的方法使用数组聚合:

    select *
    from (
        select f.id, b.name, 
            array_agg(b.name) over(partition by id) arr_names
        from foos f
        join bar_foo bf on bf.foo_id = f.id
        join bars b on b.id = bf.bar_id
    ) t
    where arr_names @> array['a', 'b'] 
    

    【讨论】:

    • 谢谢!我收到ERROR: operator does not exist: character varying[] @> text[]
    • @DevonDahon:那你需要投:where arr_names::text[] @> array['a', 'b']
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    相关资源
    最近更新 更多