问题
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