Sql 嵌套json_agg
我有一个postgresql查询,它返回一个json,其中包含所有书籍的标题、作者的名字和姓氏,以及一个包含所有书评标题+书评人的名字和姓氏的数组Sql 嵌套json_agg,sql,json,postgresql,Sql,Json,Postgresql,我有一个postgresql查询,它返回一个json,其中包含所有书籍的标题、作者的名字和姓氏,以及一个包含所有书评标题+书评人的名字和姓氏的数组 SELECT json_build_object( 'title', a.title, 'author_firstname', b.firstname, 'author_lastname', b.lastname, 'reviews', json_agg(json_build_object( 'revi
SELECT json_build_object(
'title', a.title,
'author_firstname', b.firstname,
'author_lastname', b.lastname,
'reviews', json_agg(json_build_object(
'review_title', c.title,
'reviewer_firstname', d.firstname,
'reviewer_lastname', d.lastname
))
)
FROM book AS a
INNER JOIN person AS b ON a.author_id = b.id
LEFT JOIN review AS c ON c.book_id = a.id
INNER JOIN person AS d ON c.reviewer_id = d.id
GROUP BY a.id, b.id
这很有效,而且速度很快。我需要扩展这个查询,以包括所有书名的书评人也
我遵循了第一个左连接使用的逻辑
SELECT json_build_object(
'title', a.title,
'author_firstname', b.firstname,
'author_lastname', b.lastname,
'reviews', json_agg(json_build_object(
'review_title', c.title,
'reviewer_firstname', d.firstname,
'reviewer_lastname', d.lastname,
'reviewer_books', json_agg(json_build_object(
'book_title', e.title
))
))
)
FROM book AS a
INNER JOIN person AS b ON a.author_id = b.id
LEFT JOIN review AS c ON c.book_id = a.id
INNER JOIN person AS d ON c.reviewer_id = d.id
LEFT JOIN book AS e ON e.author_id = d.id
GROUP BY a.id, b.id
但这不起作用,因为聚合函数调用不能嵌套。是否有一个解决方案,可以扩展到包括更深层的关系(如所有书评人的所有书评),并且相对有效
那些数据库把我弄糊涂了,谢谢你的帮助 您需要多个级别的聚合。这有点像:
SELECT json_build_object(
'title', b.title,
'author_firstname', p.firstname,
'author_lastname', p.lastname,
r.reviews
)
FROM book b INNER JOIN
person p
ON b.author_id = pb.id LEFT JOIN
(SELECT r.book_id,
json_agg(json_build_object('review_title', r.title,
'reviewer_firstname', pr.firstname,
'reviewer_lastname', pr.lastname,
'reviewer_books', rb.reviewer_books
)
) as reviews
FROM review r JOIN
person pr
on r.reviewer_id = pr.id JOIN
(SELECT r2.reviewer_id, json_agg(json_build_object('book_title', b2.title) as reviewer_books
FROM reviews r2 JOIN
book b2
ON r2.book_id = b2.id
GROUP BY r2.reviewer_id
) rb
on r.reviewer_id = rb.reviewer_id
) r
on r.book_id = b.id;
您需要多个级别的聚合。这有点像:
SELECT json_build_object(
'title', b.title,
'author_firstname', p.firstname,
'author_lastname', p.lastname,
r.reviews
)
FROM book b INNER JOIN
person p
ON b.author_id = pb.id LEFT JOIN
(SELECT r.book_id,
json_agg(json_build_object('review_title', r.title,
'reviewer_firstname', pr.firstname,
'reviewer_lastname', pr.lastname,
'reviewer_books', rb.reviewer_books
)
) as reviews
FROM review r JOIN
person pr
on r.reviewer_id = pr.id JOIN
(SELECT r2.reviewer_id, json_agg(json_build_object('book_title', b2.title) as reviewer_books
FROM reviews r2 JOIN
book b2
ON r2.book_id = b2.id
GROUP BY r2.reviewer_id
) rb
on r.reviewer_id = rb.reviewer_id
) r
on r.book_id = b.id;
使用任意字母作为表别名是一种非常糟糕的做法。您应该为表名使用缩写,例如
b
表示book
和p
表示person
。使用任意字母作为表别名是非常糟糕的做法。表名应使用缩写,例如b
表示book
和p
表示person
。非常感谢!多谢各位!