我想要在我的应用程序中搜索如下数据的功能
topic_id tag
1 cricket
1 football
2 football
2 basketball
3 cricket
3 basketball
4 chess
4 basketball
现在,当我搜索术语 cricket AND football
时,o/p 应该是
topic_id
1
当我搜索术语时 cricket OR football
o/p 应该是
topic_id
1
2
3
我尝试像下面这样的东西
对于和
select topic_id from table_name where tag like "%cricket%" and topic_id in (select topic_id from table_name where tag like "%football%")
为了或
select topic_id from table_name where tag like "%cricket%" OR tag like "%football%"
我的问题是,当用户搜索 cricket AND football AND basketball AND chess
时,我的查询变得非常可悲
有什么简单的解决办法吗?我也试过 GROUP_CONCAT 但没有成功
最佳答案
SELECT TopicId
FROM Table
WHERE Tag IN ('cricket', 'football', 'basketball', 'chess')
GROUP By TopicId
HAVING Count(*) = 4
4 is magic number - its a length of your AND list.
FOR cricket AND football
it will be 2:
SELECT TopicId
FROM Table
WHERE Tag IN ('cricket', 'football')
GROUP By TopicId
HAVING Count(*) = 2
if you want use 'like' statement:
SELECT TopicId
FROM Table
WHERE Tag IN (SELECT distinct Tag from Table Where Tag like '...'
OR Tag like '...'
OR Tag like '...'
OR Tag like '...'
)
GROUP By TopicId
HAVING Count(*) = (SELECT COUNT(distinct Tag) from Table
Where Tag like '...'
OR Tag like '...'
OR Tag like '...'
OR Tag like '...'
)
更新:
使用支持所有集合操作的 RDBMS 可以轻松解决此任务:UNION、INTERSECT 和EXCEPT(或MINUS)
然后任何条件如:
- (Tag1 AND Tag2)或 Tag3 NOT Tag4
- 标记 1 或标记 2
- 标签 1 和标签 2 和标签 3
- (标记 1 和标记 2)或(标记 3 和标记 4)
可以很容易地转化为:
1. (Select * ... Where Tag = Tag1
INTERSECT
Select * ... Where Tag = Tag2
)
UNION
(Select * ... Where Tag = Tag3)
EXCEPT
(Select * ... Where Tag = Tag4)
2. Select * ... Where Tag = Tag1
UNION
Select * ... Where Tag = Tag2
3. Select * ... Where Tag = Tag1
INTERSECT
Select * ... Where Tag = Tag2
INTERSECT
Select * ... Where Tag = Tag3
4.(Select * ... Where Tag = Tag1
INTERSECT
Select * ... Where Tag = Tag2
)
UNION
(Select * ... Where Tag = Tag1
INTERSECT
Select * ... Where Tag = Tag2
)
真正的问题是MYSQL不支持INTERSECT,应该模拟如上图。第二个问题是尊重括号和运算符优先级。
在表达式中不使用括号的可能解决方案:
收集所有由 AND 条件连接的标签,并构建查询作为答案中的第一个示例。
将所有加入 OR 条件(可以使用 IN 或 UNION)的标签相加,并使用 UNION 合并结果。
另一种方法只有当你的标签数量少于 64 时才有可能。然后每个标签都有自己的位(你需要将 bigint 字段'tags'添加到主题表中,其中将以二进制格式表示标签)并使用 mysql 位操作创建查询。
最大的缺点是该解决方案仅限于 64 个标签。
关于sql - 查询以根据标签查找主题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3369195/