我有下表:
f_id | word
1 foo
1 something
1 bar
2 foo
3 bar
4 else
现在,通过一些输入,我得到foo bar
值,我必须将其爆炸,然后获取包含这两个词的f_id
,而不仅仅是其中一个。
因此,对于此示例,对于foo bar
字符串,我会得到f_id = 1
,对于foo
我得到1和2,对于bar
我得到1和3.
如何进行此类查询?它必须尽可能快,因为该表有数亿条记录,并且经常被执行。
只有一个字,我在做:
SELECT * FROM table t WHERE t.word = :word
所以它非常快。
答案 0 :(得分:1)
使用LIKE查找匹配的单词。然后按f_id进行分组并计算,看看你是否找到了与搜索字符串中的单词一样多的匹配项。
select f_id
from t
where concat(' ', @words, ' ') like concat('% ', word, ' %')
group by f_id
having count(*) = length(@words) - length(replace(@words, ' ') + 1;
这取决于字符串中的单词由单个空格分隔,并且没有前导或尾随空格。因此,要么在输入字符串时要确保这一点,要么写一个存储过程将字符串转换为这种格式。
此查询速度不快。以动态方式编写查询会更快,例如:
select f_id
from t
where word in ('foo', 'bar')
group by f_id
having count(*) = 2;
(提供word
当然是索引。)
答案 1 :(得分:0)
旧查询可以在2个条件下自行连接。 查询看起来像:
SELECT t1.f_id FROM
table t1 INNER JOIN table t2
ON t1.word = :word1
AND t2.word = :word2
AND t1.f_id = t1.f_id
GROUP BY t1.f_id
要获得更好的效果:在word
列上添加索引。
答案 2 :(得分:0)
SELECT f_id FROM (
SELECT f_id, count(f_id) as count
FROM table t
WHERE t.word IN (word1,word2)
group by f_id
) t2
WHERE t2.count = 2
我相信它应该对你有帮助(我认为每个单词只显示一次f_id)