我们目前有两张桌子。一个存储有关服务器的信息,另一个存储该服务器的不同标签。这是一个简化的例子
SERVER_ID
服务器名称
TAG_ID
SERVER_ID
标签
当我们网站上的用户搜索“tag:example tag:example2”时,我们会执行查询,例如
SELECT *
FROM servers AS s
LEFT JOIN servers_tags AS st ON (st.server_id=s.server_id)
WHERE st.tag IN ("example","example2")
GROUP BY s.server_id
HAVING COUNT(DISTINCT st.tag) >= 2
有一个更好的方法可以做到这一点,因为在上面的示例中,我提供的是一些具有许多左连接的较大查询的非常简化的版本。如果用户搜索
,此解决方案将在何处进行呼叫(st.tag ='example'或st.tag ='example2')和st.tag ='example3'
在这种情况下,有计数> = 2并没有真正帮助。人们在mysql中解决这个问题的其他方法是什么?这是新的json方法吗?
答案 0 :(得分:0)
实际上,您在查询中不需要LEFT JOIN,而是INNER JOIN。你不需要没有匹配标签的服务器。
您可以使用GROUP_CONCAT收集标记列表逗号分隔(最后再添加一个comm)。然后,您可以搜索列表中的标记。
当服务器拥有全部3个标签时,tag_list为'例如,example1,example2,'
(st.tag='example' or st.tag='example2') and st.tag='example3')
案例
SELECT server_id,
CONCAT(GROUP_CONCAT(st.tag),',') as tag_list
FROM servers AS s
INNER JOIN servers_tags AS st ON (st.server_id=s.server_id)
WHERE st.tag IN ("example","example2","example3")
GROUP BY s.server_id
HAVING COUNT(DISTINCT st.tag) >= 2
AND (INSTR(tag_list, 'example,')>0 OR INSTR(tag_list, 'example1,')>0)
AND INSTR(tag_list, 'example3,')>0