Remove duplicates on MySQL JOIN query on JSON_ARRAYAGG with INNER JOIN

会有一股神秘感。 提交于 2021-01-29 05:22:57

问题


I have an app with users; the users can create bookmarks, and each bookmark can have multiple tags.

So, if I'm not mistaken in the notation: user =* bookmark *=* tag

Now I try to retrieve all users with a JSON array with the tags they used. I need a JSON array because I may need to retrieve the name or other data from the tags or the bookmarks:

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;

But this returns duplicated ids both for bookmarks and tags:

Here is a DB fiddle to play with: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=56ac0313fe2a3bf7af32a3ed9a3ea78a

How can I do that?


回答1:


This answers the original question.

You need neither the tags nor the users table for your query, so it can be much simplified.

DISTINCT is not allowed with JSON_AGG(). But you can use a subquery:

 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;

Here is a db<>fiddle.




回答2:


Ended up doing this. This way I can add more JSON objects to the main select,

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`
;

Please let me know if this is really wrong.

Here is a fiddle: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=abedb69ae4db65dd344f81a7dadb565a



来源:https://stackoverflow.com/questions/65783276/remove-duplicates-on-mysql-join-query-on-json-arrayagg-with-inner-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!