[英]Can PostgreSQL JOIN on jsonb array objects?
由於 JSON 支持,我正在考慮切換到 PostgreSQL。 但是,我想知道,是否可以通過單個查詢實現以下功能:
假設有兩個表:
表 1) 組織:
ID (INT) | members (JSONB) |
------------+---------------------------------------------------------|
1 | [{ id: 23, role: "admin" }, { id: 24, role: "default" }]|
2 | [{ id: 23, role: "user" }]
表2)用戶:
ID (INT) | name TEXT | email TEXT |
------------+-----------+---------------|
23 | Max | max@gmail.com |
24 | Joe | joe@gmail.com |
現在我想得到這樣的結果(我只有組織的 ID [1]):
ID (INT) | members (JSONB) |
------------+--------------------------------------------------------|
1 | [{ id: 23, name: "Max", email: "max@gmail.com", role:
"admin" },
{ id: 24, name: "Joe", email: "joe@gmail.com ", role:
"default" }]
(1 row)
我知道這不是 JSONB 的目的,並且有一個更好的解決方案可以將這些數據存儲在 SQL 中,但我只是好奇是否有可能。
謝謝!
是的,使用 Postgres 可以滿足此要求。 這是 9.6 或更高版本的解決方案。
SELECT o.id,
JSON_AGG(
JSON_BUILD_OBJECT('id', u.id, 'name', u.name, 'email', u.email, 'role', e.usr->'role')
)
FROM organisations o
INNER JOIN LATERAL JSONB_ARRAY_ELEMENTS(o.data) AS e(usr) ON TRUE
INNER JOIN users u ON (e.usr->'id')::text::int = u.id
GROUP BY o.id
看到這個 db fiddle 。
解釋 :
JSONB_ARRAY_ELEMENTS
函數將組織 json 數組拆分為行(每個用戶一個); 它通常與JOIN LATERAL
結合使用
為了加入users
表,我們使用->
操作符訪問id
字段的內容
對於每個用戶, JSONB_BUILD_OBJECT
用於通過傳遞值/鍵對列表來創建新對象; 大多數值來自users
表,除了role
,它取自組織 json 元素
查詢按組織 id 聚合,使用JSONB_AGG
通過組合上述對象生成 json 數組
有關更多信息,您還可以查看Postgres JSON 函數文檔。
可能有更多方法可以做到這一點。 一種方法是使用jsonb_to_recordset()
將 JSON 轉換為您可以加入的記錄集。 然后使用jsonb_build_object()
為單個成員和jsonb_agg()
從結果創建一個 JSON 以將它們聚合到 JSON 數組中。
SELECT jsonb_agg(jsonb_build_object('id', "u"."id",
'name', "u"."name",
'email', "u"."email",
'role', "m"."role"))
FROM "organisations" "o"
CROSS JOIN LATERAL jsonb_to_recordset(o."members") "m" ("id" integer,
"role" text)
INNER JOIN "users" "u"
ON "u"."id" = "m"."id";
具體可用哪些功能取決於版本。 但是既然你說你考慮切換,假設更新的版本應該是公平的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.