仅当 Postgres SQL 中存在时才将关联聚合到 JSON

Aggregate associatations to JSON only if they exist in Postgres SQL

我正在尝试 return "complete" user 对象 JSON 来自 API 由 Postgres [=41= 支持] 数据库。 users 可以属于 teams,在 table 中存储为 memberships

我的 table 是这样设置的:

Users
   id   |        email         | password |   name   | created_at 
--------+----------------------+----------+----------+------------
 user_1 | user-one@example.com | password | User One | 2015-09-17
 user_2 | user-two@example.com | password | User Two | 2015-09-17

Teams
   id   |        email         |   name   | created_at 
--------+----------------------+----------+------------
 team_1 | team-one@example.com | Team One | 2015-09-17
 team_2 | team-two@example.com | Team Two | 2015-09-17

Memberships
   id   | team_id | user_id | created_at 
--------+---------+---------+------------
 memb_1 | team_1  | user_1  | 2015-09-17
 memb_2 | team_1  | user_2  | 2015-09-17

我当前的查询:

SELECT
  users.id,
  users.email,
  users.name,
  users.created_at,
  json_agg(teams.*) AS teams
FROM users, teams, memberships
WHERE users.id=$[id]
AND users.id=memberships.user_id
AND teams.id=memberships.team_id
GROUP BY
  users.id,
  users.email,
  users.name,
  users.created_at

对于 user_1 最终 returning:

{
  "id": "user_1",
  "email": "user-one@example.com",
  "name": "User One",
  "created_at": "2015-09-17T07:00:00.000Z",
  "teams": [
    {
      "id": "team_1",
      "email": "team-one@example.com",
      "name": "Team One",
      "created_at": "2015-09-17"
    },
    {
      "id": "team_2",
      "email": "team-two@example.com",
      "name": "Team Two",
      "created_at": "2015-09-17"
    }
  ]
}

但问题是,如果我添加一个新的 user_3,他们还没有任何会员资格,所以查询最终 return 什么也没有,因为 [=21] 没有任何内容=]加入。

我如何修复此查询,以便当用户没有任何成员资格时,它最终只得到一个空的 "teams": [] 数组?

感谢您的帮助!

改用LEFT JOIN,如果在其他表上不匹配,您将得到null。

SELECT
  users.id,
  users.email,
  users.name,
  users.created_at,
  json_agg(teams.*) AS teams
FROM users
LEFT JOIN memberships
 ON users.id=memberships.user_id
LEFT JOIN teams
 ON teams.id=memberships.team_id
WHERE users.id=$[id]
GROUP BY
  users.id,
  users.email,
  users.name,
  users.created_at