如何将带有 join 的 postgresql select 转换为 json 对象?

Nel*_*ira 3 sql postgresql json join

我想将带有连接的选择结果转换为 json 对象。我的意思是这个查询:

select 
    cm.*,
    e.*,
    u.*,
from 
    chat_messages cm,
    events e,
    users u
where
    cm.event_id = e.id 
    and cm.user_id = u.id
Run Code Online (Sandbox Code Playgroud)

应该输出这个:

{
    "id": 1,
    "message": "whatever",
    "time": "2021-12-02T00:21:10.571848",
    "user": {
        "id": 35,
        "name": "John Smith"
    },
    "event": {
        "id": 19,
        "name": "Test event",
        "time":  "2021-09-22T00:00:00-03:00",
        "local": "Planet Earth"
    }
}
Run Code Online (Sandbox Code Playgroud)

(还有比这些更多的字段。我只是让示例变得简单)

我这样找到了解决方案:

select 
        json_build_object(
            'id', cm.id,
            'message', cm.message,
            'time', cm.time,
            'user', to_json(u.*),
            'event', to_json(e.*)
        )
        
from 
    chat_messages cm,
    events e,
    users u
where
    cm.event_id = e.id 
    and cm.user_id = u.id
Run Code Online (Sandbox Code Playgroud)

但我认为应该有更好的方法来做到这一点。想象一下 chat_messages 有更多的字段。逐个领域地描述​​会很冗长。我想要的是一种让查询转换 json 中的子查询的方法,而无需我逐个字段地描述。有人知道更好的方法吗?

Poo*_*oya 8

根据Postgres 文档,您可以使用该row_to_json函数将行传输到 JSON,然后为每个表行附加一个别名,以便通过row_to_json

with cte as (
  select 
    cm.*,
    e as event,
    u as user
  from 
    chat_messages cm,
    events e,
    users u
  where
    cm.event_id = e.id 
    and cm.user_id = u.id
)
select row_to_json(c) from cte c;
Run Code Online (Sandbox Code Playgroud)