SQL - 将对象附加到 json 数组的每个元素

SQL - Attach an object to each element of json array

我需要一些关于此查询的帮助。这是我目前所拥有的:


  SELECT
    p.*,
    to_json(u) AS creator,
    json_agg(c) AS comments,
    json_agg(co) AS commenter
  FROM posts p
    INNER JOIN users u ON u.id="userId"
    INNER JOIN comments c ON p.id="postId"
    INNER JOIN users co ON co.id=c."createdBy"
  WHERE p.id = ?
  GROUP BY p.id, u.id, co.id;

示例数据

POST table

"id": "5f82e0f7-e294-4b49-8f4c-7d408cd81925",
"body": "Post text",
"media": ["image", "video", "image"],
"userId": "64dfa0c1-3756-4560-9103-a1b3c4c7112b",
"createdAt": "2020-12-21T17:20:10.929Z",
"updated_at": "2020-12-21T17:20:10.929Z",

用户table

"id": "64dfa0c1-3756-4560-9103-a1b3c4c7112b",
"handle": "@bartsimpson",
"profilePicUrl": "https://pngimg.com/uploads/simpsons/simpsons_PNG12.png",
"createdAt": "2020-12-21T17:20:10.929085",
"updated_at": "2020-12-21T17:20:10.929085",
"name": "Bart Simpson",
"email": "bart@gmail.com",

评论table

"id": "cd40a98e-3d57-4d86-8f87-662492be7043",
"body": "Nice picture Bro",
"createdBy": "f58c7eda-3718-41ed-add8-1d13ef8c9268",
"postId": "5f82e0f7-e294-4b49-8f4c-7d408cd81925",
"createdAt": "2020-12-21T17:20:10.929085",
"updated_at": "2020-12-21T17:20:10.929085"

期望输出

"post": {
    "id": "5f82e0f7-e294-4b49-8f4c-7d408cd81925",
    "body": "Milhouse and I are about to go live. In this episode we are going to revisit a classic, we are going to prank Moe! Subscribe from just ",
    "likes": 22000,
    "media": [
      "https://static3.cbrimages.com/wordpress/wp-content/uploads/2020/09/simpsons-moe.jpg?q=50&fit=crop&w=960&h=500&dpr=1.5"
    ],
    "userId": "64dfa0c1-3756-4560-9103-a1b3c4c7112b",
    "createdAt": "2020-12-21T17:20:10.929Z",
    "updated_at": "2020-12-21T17:20:10.929Z",
    "creator": {
      "id": "64dfa0c1-3756-4560-9103-a1b3c4c7112b",
      "handle": "@bartsimpson",
      "profilePicUrl": "https://pngimg.com/uploads/simpsons/simpsons_PNG12.png",
      "createdAt": "2020-12-21T17:20:10.929085",
      "updated_at": "2020-12-21T17:20:10.929085",
      "name": "Bart Simpson",
      "email": "bart@gmail.com",
      "hash": "y$lFk5u4CR5yDmOjO3gYrC9elFoKuJgD7dY6rcveEBmWZD6.SSl6Vna"
    },
    "comments": [
      {
        "id": "cd40a98e-3d57-4d86-8f87-662492be7043",
        "body": "Nice picture Bro",
        "createdBy": "f58c7eda-3718-41ed-add8-1d13ef8c9268",
        "postId": "5f82e0f7-e294-4b49-8f4c-7d408cd81925",
        "createdAt": "2020-12-21T17:20:10.929085",
        "updated_at": "2020-12-21T17:20:10.929085",
        "commenter": {
            "id": "f58c7eda-3718-41ed-add8-1d13ef8c9268",
            "handle": "@homerjsimpson",
            "name": "Homer Simpson",
            "email": "homer@gmail.com",
            "profilePicUrl": "pic_url",
            "createdAt": "2020-12-21T17:20:10.929085",
            "updated_at": "2020-12-21T17:20:10.929085",
         }
      }
    ],
  }

基本上,我想将 commenter 添加到每个 comments,但我不知道如何扩展我当前的查询来做到这一点。

我是不是走错路了?如果有任何建议,我将不胜感激。

谢谢

这是在每个评论中“注入”评论者的一种方法:

select p.*,
    to_json(u) as creator,
    jsonb_agg(
        to_jsonb(c) 
        || jsonb_build_object('commenter', to_jsonb(co))
    ) as comments
from posts p
inner join users u on u.id = p.userid
inner join comments c on p.id= p.postid
inner join users co on co.id = c.created_by
where p.id = ?
group by p.id, u.id

这使用 JSONB 连接运算符 || 在每个评论数组中插入一个新键,嵌入评论记录的映射。如果您使用 json 而不是 jsonb,则需要转换值。