Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 嵌套json_agg_Sql_Json_Postgresql - Fatal编程技术网

Sql 嵌套json_agg

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

我有一个postgresql查询,它返回一个json,其中包含所有书籍的标题、作者的名字和姓氏,以及一个包含所有书评标题+书评人的名字和姓氏的数组

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
。非常感谢!多谢各位!