我不太擅长SQL,我有三个表机构、模块、文档。模块和文档属于公司。 我想选择一家拥有所有信息并按状态汇总的公司:
select "agencies".*,
JSON_AGG( modules.*) FILTER(WHERE modules.status like 'active') as activeModules,
JSON_AGG( modules.*) FILTER(WHERE modules.status like 'draft') as draftModules,
JSON_AGG( documents.*) FILTER(WHERE documents.status like 'active') as activeDocuments
from "agencies"
left outer join "modules" on "agencies"."id" = "modules"."agency_id"
left outer join "documents" on "agencies"."id" = "documents"."agency_id"
where "agencies"."id" = '959e5e04-e8ba-4367-b3d7-8bc5d5b5e666' group by "agencies"."id"
这可行,但聚合的所有记录都是重复的
如果我像这样更改选择:
JSON_AGG( DISTINCT modules.*) FILTER(WHERE modules.status like 'active') as activeModules,
它引发错误:错误:无法识别类型模块的相等运算符
我通过这样做找到了解决方案:
JSON_AGG( distinct jsonb_build_object(modules.id, modules.field2...) ) FILTER(WHERE modules.status like 'active') as activeModules,
这可行,但我不喜欢指定所有字段的想法。 有没有一种方法可以实现我想要的而不需要插入所有字段?
您可以尝试编写查询以使用子查询来查找 JSON 聚合:
SELECT a.*, m.activeModules, m.draftModules, d.activeDocuments
FROM agencies a
LEFT JOIN
(
SELECT agency_id,
JSON_AGG(*) FILTER (WHERE status LIKE 'active') AS activeModules,
JSON_AGG(*) FILTER (WHERE status LIKE 'draft') AS draftModules
FROM modules
GROUP BY agency_id
) m
ON a.id = m.agency_id
LEFT JOIN
(
SELECT agency_id,
JSON_AGG(*) FILTER (WHERE status LIKE 'active') AS activeDocuments
FROM documents
GROUP BY agency_id
) d
ON a.id = d.agency_id
WHERE a.id = '959e5e04-e8ba-4367-b3d7-8bc5d5b5e666'
GROUP BY a.id;