如果我有一个字符串,我可以看到是否有子字符串的记录

时间:2015-01-28 04:02:18

标签: sql postgresql select

如果我有一个字符串'这是一个好的字符串'
我在数据库中有三条记录

1,"好"
2,"放屁"
3,"这个"

有没有办法查找作为我的源的子串的记录..

我问,因为我有一个black_list表,其中包含我从不想让我的用户存储的条目。就像他们想要存储www.google.com一样,我有" google"在我的黑名单中,我从存在中获得了积极的结果,并知道不要让他们......

我会继续挖掘,我可能会在这里发布我的答案,但要弄清楚这是一件有趣的事情。我宁愿在DB层中而不是在ruby / rails层中这样做。

2 个答案:

答案 0 :(得分:2)

如果您只想匹配整个单词,那么使用更大的表会更快 ,因为它可以使用entry上的索引(与您的解决方案不同,谓词的位置)不是sargable):

简单

假设空格为单词分隔符(\s+)。

SELECT *
FROM   black_list 
JOIN   regexp_split_to_table('the task description', '\s+') entry USING (entry)

高级

对于更具体的需求,您可以定制您提取的单词:

  • \m的分词(由POSIX标准定义)。 Per documentation:

    matches only at the beginning of a word
    
  • 删除要忽略的前导,尾随或所有字符。由于我们在单词的开头处拆分,因此尾随字符可能就足够了。

  • 最后转换为小写 - 假设black_list中的小写条目:

基本和快速

分割单词并修剪给定的尾随字符:

SELECT *
FROM   black_list 
JOIN  (
   SELECT rtrim(w, ' /\,.-') AS entry -- add more?
   FROM   regexp_split_to_table('Oh - my, a4b smurf-village in/out.', '\m') w
   ) w USING (entry);

彻底

分词,删除所有非单词字符并转换为小写字母:

SELECT *
FROM   black_list 
JOIN  (
   SELECT lower(regexp_replace(w, '\W+', '')) AS entry
   FROM   regexp_split_to_table('Oh - my, a4b smurf-village in/out.', '\m') w
   ) w USING (entry);

SQL Fiddle.

除了

您可以更进一步,测试相似性以捕获拼写错误。但你必须权衡alpha与beta错误(错误排除法律词语)。

SELECT set_limit(0.9); -- high example value

SELECT *
FROM   black_list b
JOIN  (
   SELECT lower(regexp_replace(w, '\W+', '')) AS entry
   FROM   regexp_split_to_table('Oh - my, a4b smurf-village in/out.', '\m') w
   ) w ON b.entry % w.entry

%运算符需要额外的模块pg_trgm。详细说明:

答案 1 :(得分:0)

它花费的时间比我想象的少得多......主要是因为我尝试了不同的东西。

select * from black_list 
where 'this is the task description' like concat('%', entry, '%')

对于rails dev那里

 scope :part_of, ->(source) { where("? like concat('%', entry, '%')", source) }


 BlackList.part_of('this is a test fire').exists?
 BlackList.part_of(task.description).exists?