0

我有一个用户应用程序;用户可以创建书签,每个书签可以有多个标签。

所以,如果我没记错的话:user =* bookmark *=* tag

现在我尝试使用带有他们使用的标签的 JSON 数组检索所有用户。我需要一个 JSON 数组,因为我可能需要从标签或书签中检索名称或其他数据:

SELECT
  `user`.id,
  JSON_ARRAYAGG(
    JSON_OBJECT(
      "id", tag.id
    )
  ) AS tags,
  JSON_ARRAYAGG(
    JSON_OBJECT(
      "id", bookmark.id
    )
  ) AS bookmarks
FROM tag
INNER JOIN bookmark_tag ON bookmark_tag.tag_id = tag.id
INNER JOIN bookmark ON bookmark.id = bookmark_tag.bookmark_id
INNER JOIN `user` ON user.id = bookmark.user_id
GROUP BY `user`.id;

但这会为书签和标签返回重复的 id:

这是一个可以玩的数据库小提琴:https ://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=56ac0313fe2a3bf7af32a3ed9a3ea78a

我怎样才能做到这一点?

4

2 回答 2

0

这回答了最初的问题。

您的查询既不需要 也不需要tagsusers,因此可以大大简化。

DISTINCT不允许与JSON_AGG(). 但是您可以使用子查询:

 SELECT b.user_id, JSON_ARRAYAGG( b.tag_id) AS tags
 FROM (SELECT DISTINCT b.user_id, bt.tag_id
       FROM bookmark_tag bt JOIN
            bookmark b 
            ON b.id = bt.bookmark_id
      ) b
 GROUP BY b.user_id;

是一个 db<>fiddle。

于 2021-01-18T23:09:29.303 回答
0

最终这样做了。这样我可以向主选择添加更多 JSON 对象,

SELECT
  `user`.`id`,
  (
    SELECT
      JSON_ARRAYAGG(
        JSON_OBJECT(
          'id', subQuery.id,
          'name', subQuery.name
        )
      )
      FROM (
        SELECT DISTINCT
        bookmark.user_id,
          tag.id,
          tag.name
        FROM tag
        INNER JOIN bookmark_tag ON bookmark_tag.tag_id = tag.id
        INNER JOIN bookmark ON bookmark.id = bookmark_tag.bookmark_id
        INNER JOIN `user` ON user.id = bookmark.user_id
      ) subQuery
      WHERE user.id = subQuery.user_id
  ) AS tags,
  (
    SELECT
      JSON_ARRAYAGG(
        JSON_OBJECT(
          'id', bookmark.id
        )
      )
    FROM bookmark
    WHERE user.id = bookmark.user_id
  ) AS bookmarks
  FROM `user`
  GROUP BY `user`.`id`
;

请让我知道这是否真的错了。

这是一个小提琴:https ://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=abedb69ae4db65dd344f81a7dadb565a

于 2021-01-19T00:47:31.093 回答