@Kneepy

Group_concat внутри другого group_concat?

Есть следующий запрос
SELECT
           p.title, p.supplement, p.link, p.file, uPost.avatar, p.pid, uPost.lastname, 
           CONCAT(IFNULL(uPost.firstname, ''), ' ', IFNULL(uPost.surname, '')) AS name,
           uPost.uid, 
           GROUP_CONCAT(JSON_ARRAY(
             JSON_OBJECT(
               'name', CONCAT(IFNULL(uComm.firstname, ''), " ", IFNULL(uComm.surname, '')),
               'avatar', uComm.avatar,
               'lastname', uComm.lastname,
               'value', c.value,
               'cid', c.cid, 
               'answers', JSON_ARRAY(
                  JSON_OBJECT(
                    'name', CONCAT(IFNULL(usersAnswerComm.firstname, ''), " ", IFNULL(usersAnswerComm.surname, '')), 
                    'avatar', usersAnswerComm.avatar, 
                    'lastname', usersAnswerComm.lastname, 
                    'value', cAnswer.value, 
                    'cid', cAnswer.cid, 
                    'answer', cAnswer.answer
                  )
               )
             )
           )) AS comments 
           FROM posts p 
             JOIN users uPost ON p.uid = uPost.uid AND p.pid = ?
             LEFT JOIN comments c ON c.pid = ?
             LEFT JOIN users uComm ON uComm.uid = c.uid
             LEFT JOIN comments cAnswer ON cAnswer.answer = c.cid
             JOIN users usersAnswerComm ON usersAnswerComm.uid = cAnswer.uid

Но вывод answers происходит по одному к каждому комментарию, а не группой. То есть когда я пытаюсь вывести ответы для одного комментария, выводятся они не под одним комментарием, а по одному под каждым. Как нужно перестроить запрос чтобы это работало как было упомянуто выше?
  • Вопрос задан
  • 117 просмотров
Решения вопроса 1
@Kneepy Автор вопроса
Кому интересна судьба этого запроса, то я пришёл к такому решению
SELECT
             p.title, p.supplement, p.link, p.file, uPost.avatar, p.pid, uPost.lastname,
             CONCAT(IFNULL(uPost.firstname, ''), ' ', IFNULL(uPost.surname, '')) AS name,
             uPost.uid, 
             GROUP_CONCAT(distinct JSON_ARRAY(
                 JSON_OBJECT(
                   'name', CONCAT(IFNULL(uComm.firstname, ''), " ", IFNULL(uComm.surname, '')),
                   'avatar', uComm.avatar,
                   'lastname', uComm.lastname,
                   'value', c.value,
                   'cid', c.cid, 
                   'isAnswer', IFNULL(c.answer, false),
                   'answers', (SELECT GROUP_CONCAT(JSON_ARRAY(JSON_OBJECT(
                   		'name', CONCAT(IFNULL(uComm.firstname, ''), " ", IFNULL(uComm.surname, '')),
                       	'avatar', uComm.avatar,
                       	'lastname', uComm.lastname,
                       	'value', commAnswer.value,
                       	'cid', commAnswer.cid
                   ))) AS answer FROM comments commAnswer WHERE commAnswer.answer = c.cid)
                 )
             )) AS comments
           FROM posts p 
             JOIN users uPost ON p.uid = uPost.uid AND p.pid = ?
             LEFT JOIN comments c ON c.pid = ?
             LEFT JOIN users uComm ON uComm.uid = c.uid
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Если максимум - это ответы на комментарии, то как-то так:
SELECT `p`.`title`, `p`.`supplement`, `p`.`link`, `p`.`file`,
	    `u`.`avatar`, `p`.`pid`, `u`.`lastname`, `u`.`uid`, `c`.`comments`,
       CONCAT(IFNULL(`u`.`firstname`, ''), ' ', IFNULL(`u`.`surname`, '')) AS `name`
  FROM (
    SELECT `c`.`pid`,
           JSON_ARRAYAGG(JSON_OBJECT(
             'name', CONCAT(IFNULL(`u`.`firstname`, ''), " ", IFNULL(`u`.`surname`, '')),
             'avatar', `u`.`avatar`,
             'lastname', `u`.`lastname`,
             'value', `c`.`value`,
             'cid', `c`.`cid`,
             'answers', `a`.`answers`
           )) AS `comments`
	  FROM (
        SELECT `a`.`cid`,
               JSON_ARRAYARG(JSON_OBJECT(
                 'name', CONCAT(IFNULL(`u`.`firstname`, ''), " ", IFNULL(`u`.`surname`, '')), 
                 'avatar', `u`.`avatar`, 
                 'lastname', `u`.`lastname`, 
                 'value', `a`.`value`, 
                 'cid', `a`.`cid`, 
                 'answer', `a`.`answer`
               )) AS `answers`
          FROM `comments` AS `c`
          JOIN `comments` AS `a` ON `a`.`cid` = `c`.`cid`
          LEFT JOIN `users` AS `u` ON `u`.`uid` = `a`.`uid`
          WHERE `c`.`pid` = :postId
          GROUP BY `a`.`cid`
      ) AS `a`
      RIGHT JOIN `comments` AS `c` ON `c`.`cid` = `a`.`cid`
      LEFT JOIN `users` AS `u` ON `c`.`uid` = `u`.`uid`
      WHERE `c`.`pid` = :postId
      GROUP BY `c`.`pid`
  ) AS `c`
  RIGHT JOIN `posts` AS `p` ON `p`.`pid` = `c`.`pid`
  LEFT JOIN `users` AS `u` ON `u`.`uid` = `p`.`uid`
  WHERE `p`.`pid` = :postId

Если нужно дерево комментариев, то получать всё дерево построчно и строить JSON в приложении.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы