获取关联属性作为数组 - 其中存在给定的 属性

Get associated properties as array - where a given property exists

我有一个 table tbl_a.

 id | name
----+-------
  1 | item1
  2 | item2
  3 | item3

我还有一个 table tbl_aprops,它存储与 tbl_a 中的项目 a 关联的属性 prop

 a_id | prop
------+------
    1 | xx
    1 | yy
    2 | xx
    2 | zz
    3 | yy

我希望执行 LEFT JOIN,其中返回左侧 table tbl_a 的所有信息以及来自 table_aprops 的相关属性 prop在名为 props 的新列中的数组中。我希望过滤掉与 属性 'yy' 关联的 not 项目,同时仍返回 all 关联属性 prop来自 tbl_aprops.

 id | name  |   props
----+-------+-----------
  1 | item1 | {'xx','yy'}
  3 | item3 | {'yy'}

可以使用以下查询来实现此目的:

SELECT z.*
FROM tbl_aprops b
JOIN (
  SELECT a.* AS id, array_agg(p.prop) props
  FROM tbl_a a
  LEFT JOIN tbl_aprops p
  ON a.id = p.a_id
  GROUP BY a.id) z
ON z.id = b.a_id
WHERE b.prop = 'yy';

不过,我愿意接受提高此查询效率的建议。

I wish to filter out items not associated with property 'yy' while still returning all associated properties prop from tbl_aprops.

SELECT *
FROM   tbl_a a
JOIN  (
   SELECT a_id AS id, array_agg(x.prop) AS props
   FROM   tbl_aprops y
   JOIN   tbl_aprops x USING (a_id)
   WHERE  y.prop = 'yy'
   GROUP  BY 1
   ) b USING (id);

db<>fiddle here

在子查询 a 中,使用 WHERE prop = 'yy' 和自连接过滤后聚合数组。每个符合条件的项目只生成一行。然后加入tabletbl_a。瞧。
值得注意的是:No LEFT JOIN for this.

为了方便我在子查询中将a_id重命名为id,所以我可以加入USING (id)。那只有returns列的单个副本,而SELECT *returns我们所需要的,没有多余的列。

为获得最佳性能,请在 tbl_aprops(prop, a_id) 上设置 索引
以及 tbl_aprops(a_id, prop)tbl_a(id) 上的索引(使用反向列序列!)。考虑: