使用SQL GROUP_CONCAT

时间:2019-06-01 08:46:19

标签: php mysql sql

我有这个comments表来存储每个帖子的所有评论

comment_id    comment_message    posts_id   u_id   created
=============================================================
46            comments....       2          6      1559376498
47            comments....       2          6      1559376502
48            comments....       2          6      1559376598
每个评论反应(r_id)

comments_like

cl_id    comment_id   posts_id    u_id   r_id   created
=============================================================
42       46           2           6      6     1559376598
43       47           2           6      2     1559376598
44       48           2           6      8     1559376598
45       46           2           1      2     1559376598

注意:posts_id表示帖子表ID,u_id表示用户表ID,r_id表示反应ID,comment_id表示评论表ID 。

现在,我想获取特定ID的所有注释,其中包含反应ID的列表和由登录用户提供的反应ID的列表。

为此,我正在使用以下SQL查询,但未显示我的预期结果:(

$query = $this->_db->_pdo->prepare("
            SELECT c.*, u.u_id, u.full_name, cl.r_id, GROUP_CONCAT(cl.r_id ORDER BY cl.u_id) AS r_id
            FROM comments AS c 
            LEFT JOIN users AS u ON c.u_id = u.u_id 
            LEFT JOIN comments_like AS cl ON cl.comment_id = c.comment_id 
            WHERE c.posts_id = '$post_id' 
            ORDER BY c.comment_id  ");  

此查询的输出应为

1)特定帖子ID($ post_id)的所有评论;
2)反应ID的列表
3)登录用户的反应ID。

2 个答案:

答案 0 :(得分:0)

您在查询中缺少一个GROUP BY子句,因此它将所有注释分组为一行;您需要按c.comment_id分组。这应该给您想要的结果:

SELECT c.*, u.u_id, u.full_name, cl.r_id, 
       GROUP_CONCAT(cl.r_id ORDER BY cl.u_id) AS r_id
FROM comments AS c 
LEFT JOIN users AS u ON c.u_id = u.u_id 
LEFT JOIN comments_like AS cl ON cl.comment_id = c.comment_id 
WHERE c.posts_id = 2
GROUP BY c.comment_id
ORDER BY c.comment_id

输出:

comment_id  comment_message posts_id    u_id    created     u_id    full_name   r_id
46          comments....    2           6       1559376498  6       Bill Jones  2,6
47          comments....    2           6       1559376502  6       Bill Jones  2
48          comments....    2           6       1559376598  6       Bill Jones  8

Demo on dbfiddle

答案 1 :(得分:0)

您似乎也想要特定用户的反应ID。如果是这样:

SELECT c.*, u.u_id, u.full_name,
       MAX(ASE WHEN cl.u_id = ? THEN cl.r_id END) as specific_user_reaction, 
       GROUP_CONCAT(cl.r_id ORDER BY cl.u_id) AS r_id
FROM comments c LEFT JOIN
     users u
     ON c.u_id = u.u_id LEFT JOIN
     comments_like cl
     ON cl.comment_id = c.comment_id 
WHERE c.posts_id = ?
GROUP BY c.comment_id, u.u_id, u.full_name
ORDER BY c.comment_id;

?用于参数。这就是将值传递到准备好的语句中的方式(而不是浪费查询字符串)。

第一个?用于您想要其反应的用户。第二个是您想要的帖子(原始代码中的$post_id)。如果您需要更多有关传递参数的信息,可以查看准备好的语句中的documentation