【问题标题】:Remove duplicates on MySQL JOIN query on JSON_ARRAYAGG with INNER JOIN使用 INNER JOIN 删除 JSON_ARRAYAGG 上 MySQL JOIN 查询的重复项
【发布时间】:2021-04-23 06:25:15
【问题描述】:

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

所以,如果我没记错的话: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:

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

我该怎么做?

【问题讨论】:

    标签: mysql sql join json-arrayagg


    【解决方案1】:

    这回答了最初的问题。

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

    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;
    

    Here 是一个 dbfiddle。

    【讨论】:

    • 注: mariadb 确实允许与 json_arrayagg 不同
    【解决方案2】:

    最终这样做了。这样我可以将更多 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

    【讨论】:

      猜你喜欢
      • 2012-07-24
      • 1970-01-01
      • 2016-01-02
      • 2021-03-04
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多