我有这个数据库模式。我只是为了简单起见而调用我标记对象的东西:
用户
- 用户身份
- 登录
用户到对象表(多对多)
- 用户身份
- object_id
对象表
- object_id
- object_stuff
使用 user_id 表标记的对象(带有额外列的多对多)
- 用户身份
- object_id
- tag_id
标记表
- tag_id
- 标签名
我一直在使用这样的查询来获取特定用户的对象以及对象的标签(如果用户标记了任何标签)。如果您认为可以优化这一点,请随时告诉我。
@user_id = 'whatever user_id I want';
SELECT
o.object_id AS object_id,
o.object_stuff AS object_stuff,
IF (tags.tag_name IS NOT NULL, GROUP_CONCAT(tags.tag_name SEPARATOR '|'), 'N/A') AS tags
FROM object_table AS o
LEFT OUTER JOIN obj_to_users_table AS o2u ON o.object_id = o2u.object_id
LEFT OUTER JOIN users AS u ON u.user_id = o2u.user_id
LEFT OUTER JOIN obj_to_tag_users AS o2tu ON o.object_id = o2tu.object_id AND u.user_id = o2tu.user_id
LEFT OUTER JOIN tags AS t ON t.tag_id = o2t.tag_id
WHERE u.user_id = @user_id GROUP BY o.object_id
这将产生如下结果:
object_id object_stuff tags
1 stuff1... tag1|tag2|tag3
2 stuff2... tag4|tag6|tag1
3 stuff3... tag7|tag2|tag5
我的问题是,例如,我想搜索标记为“tag2”的对象,我应该得到:
object_id object_stuff tags
1 stuff1... tag1|tag2|tag3
3 stuff3... tag4|tag2|tag1
但是相反,我丢失了该对象附带的其他标签:
object_id object_stuff tags
1 stuff1... tag2
3 stuff3... tag2
如何修改我的 WHERE 子句,以便我可以获得标记为“tag2”的对象,同时保留该对象在结果集中具有的其他标记?
... WHERE u.user_id = @user_id AND t.tag_name LIKE '%tag2%' ...