PSQL Join 替代 return 所有行

PSQL Join alternative to return all rows

我有一个 PSQL 函数,其中有 3 个连接,数据在 json 对象中返回。我有第 4 个 table 需要从中获取数据,但它与我希望加入的 table 具有一对多关系。

这是我当前的代码:

select json_agg(row_to_json(s)) as results from (
                select g.*,row_to_json(o.*) as e_occurence,
                row_to_json(d.*) as e_definition,
                row_to_json(u.*) as e_e_updates,
                cardinality(o.m_ids) as m_count
                from schema.e_group g
                join schema.e_occurrence o on g.id = o.e_group_id
                join schema.e_definition d on g.e_id = d.id
                left join schema.e_e_updates u on d.id = u.e_id
                ) s

这为我提供了一组遵循以下粗略结构的对象:

[
    {
        "id": 11308158,
        "e_id": 16,
        "created_on": "2020-09-09T12:08:07.556062",
        "event_occurence": {
            "id": 9081887,
            "e_id": 16,
            "e_group_id": 11308158
        },
        "e_definition": {
            "id": 16,
            "name": "Placeholder name"
        },
        "e_e_updates": {
            "id": 22,
            "user_id": "7281057e-2876-1673-js7d-7cqj611b4557",
            "e_id": 16
        },
        "m_count": 0
    }
]

我的问题是 table e_e_updates 每个对应的 e_definition.id 可以有多个记录。

很明显,在这种情况下,连接不会像希望的那样工作,因为我希望 e_e_updates 成为所有链接行的数组。

是否有解决此问题的替代方法?

基本上,您需要另一个聚合级别。这应该可以满足您的要求:

select json_agg(row_to_json(s)) as results 
from (
    select 
        g.*,
        row_to_json(o.*) as e_occurence,
        row_to_json(d.*) as e_definition,
        u.u_arr as e_e_updates,
        cardinality(o.m_ids) as m_count
    from schema.e_group g
    join schema.e_occurrence o on g.id = o.e_group_id
    join schema.e_definition d on g.e_id = d.id
    left join (
        select e_id, json_agg(row_to_json(*)) u_arr
        from schema.e_e_updates
        group by on e_id
    ) u on d.id = u.e_id
) s

您也可以使用子查询来做到这一点:

select json_agg(row_to_json(s)) as results 
from (
    select 
        g.*,
        row_to_json(o.*) as e_occurence,
        row_to_json(d.*) as e_definition,
        (
            select json_agg(row_to_json(u.*))
            from schema.e_e_updates u
            where u.e_id = d.id
        ) as e_e_updates,
        cardinality(o.m_ids) as m_count
    from schema.e_group g
    join schema.e_occurrence o on g.id = o.e_group_id
    join schema.e_definition d on g.e_id = d.id
) s