2016-05-11 137 views
1

我有三個表帖子評論,並用戶。帖子表包括兩類帖子,問題回答。對問題和答案進行評論。我的目的是得到一個關於它的評論,對它的回答和對這個答案的評論。此外,我需要用戶名錶作爲每個問題的作者,我提取的答案和評論。我正在使用Postgres 9.5,並使用json_agg()函數。重複條目JOIN查詢

雖然示例輸出我需要的應該是類似先上後下的東西,我得到重複條目。

我在這裏錯過了什麼?通過子句正確的分組可能是。或者子查詢收集他們的意見的答案是不是做到這一點。當我評論註釋表中帖子的左連接時,我會得到理想的結果,而不會對問題發表評論。另外,當我取消包含子查詢的左連接時,我得到了非重複性結果,並且這又不是我想要的完整數據集。這些是我迄今收集的解決我的問題的事情。

我需要什麼:

[ 
    { 
    "post_id": "10", 
    "created_at": "2016-05-10T00:16:54.469Z", 
    "post_type": "question", 
    "post_title": "qwerty", 
    "post_text": "asdasd asda sdasd", 
    "post_author_id": 1, 
    "author": "isikfsc", 
    "parent_post_id": null, 
    "is_accepted": null, 
    "acceptor_id": null, 
    "answers": [ 
     { 
     "post_id": 17, 
     "created_at": "2016-05-10T04:58:56.350229", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "222asda dasdad asdada", 
     "post_author_id": 1, 
     "author": "isikfsc", 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 5, 
      "created_at": "2016-05-10T10:56:30.220128", 
      "text": "qweqwe", 
      "author_id": 1, 
      "author": "isikfsc", 
      "parent_post_id": 17 
      }, 
      { 
      "id": 8, 
      "created_at": "2016-05-10T11:00:00.182991", 
      "text": "sasasd", 
      "author_id": 1, 
      "author": "isikfsc", 
      "parent_post_id": 17 
      } 
     ] 
     }, 
     { 
     "post_id": 14, 
     "created_at": "2016-05-10T04:19:19.005556", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "asdasdasdasd", 
     "post_author_id": 1, 
     "author": "isikfsc", 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 2, 
      "created_at": "2016-05-10T05:25:34.671008", 
      "text": "qeqweqwe", 
      "author_id": 1, 
      "author": "isikfsc", 
      "parent_post_id": 14 
      } 
     ] 
     } 
    ], 
    "comments": [ 
     { 
      "id": 1, 
      "created_at": "2016-05-10T10:56:30.220128", 
      "text": "qweqwe", 
      "author_id": 1, 
      "author": "isikfsc", 
      "parent_post_id": 10 
     }, 
     { 
      "id": 4, 
      "created_at": "2016-05-10T11:00:00.182991", 
      "text": "sasasd", 
      "author_id": 1, 
      "author": "isikfsc", 
      "parent_post_id": 10 
     } 
    ] 
    } 
] 

我的查詢是:

SELECT 
    q.*, 
    json_agg(ac.*) AS answers, 
    json_agg(c.*) AS comments --comments on posts of post_id questions 
FROM posts q 

LEFT JOIN 
    (
     SELECT 
      a.*, 
      json_agg(c.*) AS comments -- comments on posts of post_id answers 
     FROM posts a 
     LEFT JOIN comments c 
     ON a.post_id = c.parent_post_id 

     GROUP BY a.post_id 
    ) ac 
ON q.post_id = ac.parent_post_id 

LEFT JOIN comments c 
ON q.post_id = c.parent_post_id 

WHERE q.post_id = 10 
GROUP BY q.post_id 

我能得到什麼:

[ 
    { 
    "post_id": "10", 
    "created_at": "2016-05-10T00:16:54.469Z", 
    "post_type": "question", 
    "post_title": "qwerty", 
    "post_text": "asdasd asda sdasd", 
    "post_author_id": 1, 
    "parent_post_id": null, 
    "is_accepted": null, 
    "acceptor_id": null, 
    "answers": [ 
     { 
     "post_id": 17, 
     "created_at": "2016-05-10T04:58:56.350229", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "222asda dasdad asdada", 
     "post_author_id": 1, 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 5, 
      "created_at": "2016-05-10T10:56:30.220128", 
      "text": "qweqwe", 
      "author_id": 1, 
      "parent_post_id": 17 
      }, 
      { 
      "id": 8, 
      "created_at": "2016-05-10T11:00:00.182991", 
      "text": "sasasd", 
      "author_id": 1, 
      "parent_post_id": 17 
      } 
     ] 
     }, 
     { 
     "post_id": 17, 
     "created_at": "2016-05-10T04:58:56.350229", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "222asda dasdad asdada", 
     "post_author_id": 1, 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 5, 
      "created_at": "2016-05-10T10:56:30.220128", 
      "text": "qweqwe", 
      "author_id": 1, 
      "parent_post_id": 17 
      }, 
      { 
      "id": 8, 
      "created_at": "2016-05-10T11:00:00.182991", 
      "text": "sasasd", 
      "author_id": 1, 
      "parent_post_id": 17 
      } 
     ] 
     }, 
     { 
     "post_id": 17, 
     "created_at": "2016-05-10T04:58:56.350229", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "222asda dasdad asdada", 
     "post_author_id": 1, 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 5, 
      "created_at": "2016-05-10T10:56:30.220128", 
      "text": "qweqwe", 
      "author_id": 1, 
      "parent_post_id": 17 
      }, 
      { 
      "id": 8, 
      "created_at": "2016-05-10T11:00:00.182991", 
      "text": "sasasd", 
      "author_id": 1, 
      "parent_post_id": 17 
      } 
     ] 
     }, 
     { 
     "post_id": 17, 
     "created_at": "2016-05-10T04:58:56.350229", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "222asda dasdad asdada", 
     "post_author_id": 1, 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 5, 
      "created_at": "2016-05-10T10:56:30.220128", 
      "text": "qweqwe", 
      "author_id": 1, 
      "parent_post_id": 17 
      }, 
      { 
      "id": 8, 
      "created_at": "2016-05-10T11:00:00.182991", 
      "text": "sasasd", 
      "author_id": 1, 
      "parent_post_id": 17 
      } 
     ] 
     }, 
     { 
     "post_id": 14, 
     "created_at": "2016-05-10T04:19:19.005556", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "asdasdasdasd", 
     "post_author_id": 1, 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 2, 
      "created_at": "2016-05-10T05:25:34.671008", 
      "text": "qeqweqwe", 
      "author_id": 1, 
      "parent_post_id": 14 
      } 
     ] 
     }, 
     { 
     "post_id": 14, 
     "created_at": "2016-05-10T04:19:19.005556", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "asdasdasdasd", 
     "post_author_id": 1, 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 2, 
      "created_at": "2016-05-10T05:25:34.671008", 
      "text": "qeqweqwe", 
      "author_id": 1, 
      "parent_post_id": 14 
      } 
     ] 
     }, 
     { 
     "post_id": 14, 
     "created_at": "2016-05-10T04:19:19.005556", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "asdasdasdasd", 
     "post_author_id": 1, 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 2, 
      "created_at": "2016-05-10T05:25:34.671008", 
      "text": "qeqweqwe", 
      "author_id": 1, 
      "parent_post_id": 14 
      } 
     ] 
     }, 
     { 
     "post_id": 14, 
     "created_at": "2016-05-10T04:19:19.005556", 
     "post_type": "answer", 
     "post_title": null, 
     "post_text": "asdasdasdasd", 
     "post_author_id": 1, 
     "parent_post_id": 10, 
     "is_accepted": null, 
     "acceptor_id": null, 
     "comments": [ 
      { 
      "id": 2, 
      "created_at": "2016-05-10T05:25:34.671008", 
      "text": "qeqweqwe", 
      "author_id": 1, 
      "parent_post_id": 14 
      } 
     ] 
     } 
    ], 
    "comments": [ 
     { 
     "id": 1, 
     "created_at": "2016-05-10T05:25:28.200327", 
     "text": "asadasdad", 
     "author_id": 1, 
     "parent_post_id": 10 
     }, 
     { 
     "id": 4, 
     "created_at": "2016-05-10T10:25:23.381177", 
     "text": "werwer", 
     "author_id": 1, 
     "parent_post_id": 10 
     }, 
     { 
     "id": 1, 
     "created_at": "2016-05-10T05:25:28.200327", 
     "text": "asadasdad", 
     "author_id": 1, 
     "parent_post_id": 10 
     }, 
     { 
     "id": 4, 
     "created_at": "2016-05-10T10:25:23.381177", 
     "text": "werwer", 
     "author_id": 1, 
     "parent_post_id": 10 
     }, 
     { 
     "id": 1, 
     "created_at": "2016-05-10T05:25:28.200327", 
     "text": "asadasdad", 
     "author_id": 1, 
     "parent_post_id": 10 
     }, 
     { 
     "id": 4, 
     "created_at": "2016-05-10T10:25:23.381177", 
     "text": "werwer", 
     "author_id": 1, 
     "parent_post_id": 10 
     }, 
     { 
     "id": 1, 
     "created_at": "2016-05-10T05:25:28.200327", 
     "text": "asadasdad", 
     "author_id": 1, 
     "parent_post_id": 10 
     }, 
     { 
     "id": 4, 
     "created_at": "2016-05-10T10:25:23.381177", 
     "text": "werwer", 
     "author_id": 1, 
     "parent_post_id": 10 
     } 
    ] 
    } 
] 

回答

1

分組發生一次各方已經連接,所以聚集將取決於由此產生的基數。加入包含答案和評論的帖子會導致它們之間的完全聯接,重複所有值。他們需要分開單獨進行,你可以做一個方法如下:

SELECT 
    q.*, 
    (SELECT json_agg(ac.*) 
    FROM (
     SELECT a.*, json_agg(c.*) AS comments 
     FROM posts a 
     LEFT JOIN comments c ON (a.post_id = c.parent_post_id) 
     WHERE a.parent_post_id = q.post_id 
     GROUP BY a.post_id 
     ) ac 
    ) AS answers, 
    json_agg(c.*) AS comments --comments on posts of post_id questions 
FROM posts q 
LEFT JOIN comments c ON (q.post_id = c.parent_post_id) 
WHERE q.post_id = 10 
GROUP BY q.post_id; 

或者:

SELECT q.*, qa.answers, qc.comments 
FROM posts q 
LEFT JOIN (
    SELECT ac.parent_post_id, json_agg(ac.*) AS answers 
    FROM (
    SELECT ac.*, json_agg(c.*) AS comments 
    FROM posts ac 
    LEFT JOIN comments c ON (c.parent_post_id = ac.post_id) 
    GROUP BY ac.post_id 
    ) ac 
    GROUP BY ac.parent_post_id 
) qa ON (qa.parent_post_id = q.post_id) 
LEFT JOIN (
    SELECT c.parent_post_id, json_agg(c.*) AS comments 
    FROM comments c 
    GROUP BY c.parent_post_id 
) qc ON (qc.parent_post_id = q.post_id) 
WHERE q.post_id = 10; 
+0

我從這些查詢兩個錯誤消息,在我的終端。第一個是前者:'[error:語法錯誤處於或接近'。「]'和第二個後者:'[error:語法錯誤處於或接近」FROM「]'。我找不到原因?我一直在檢查弄清楚。 –

+0

通過'LEFT JOIN評論C(q.post_id = c.parent_post_id)'你的意思'LEFT JOIN評論C對q.post_id = c.parent_post_id' –

+0

@ ISIK是,固定兩個錯誤現在 –