进行反向包含搜索的SQL查询?

5

我需要搜索文章标签字符串,这些字符串是用户输入字符串的子字符串。

因此,在下面的示例中,如果用户搜索“normal”,查询应该返回文章1和文章3,因为文章3具有通配符标签“norm*”。 如果我搜索“normalization”,那么我应该得到文章3和文章4。 如果需要更清晰地解释我的问题,请告诉我。

示例-

  • 文章1标签= normal
  • 文章2标签= apple
  • 文章3标签= norm*
  • 文章4标签= normalization
  • 文章5标签= corvette

注意- 我只需要在以*结尾的标签上执行子字符串搜索。


2
你在哪个数据库里?这可能会更复杂,因为“%”是通配符。 - Twelfth
选择*从文章中,其中ID不在(选择ID从文章中,其中标签类似于“foo”) - Carl Manaster
正则表达式和通配符不兼容。 - user557597
你能把数据分成两列吗?第三列是 norm | true,第一列是 normal | false - Daniel Kaplan
3个回答

6

最简单的方法,但可能不是最有效的方法,是在您的表中将所有*替换为%并使用LIKE语句:

SELECT
  Tag
FROM
  Article
WHERE
  'normal' LIKE REPLACE(Tag, '*', '%')

SqlFiddle中查看示例


+1 聪明,性能比我可怕的解决方案更好。我考虑过这个,但认为它不会起作用,所以从未尝试过 ;) - jpw
谢谢,这在SqlFiddle中似乎起作用了,希望它在Sqlite (win8通用应用程序)中也能正常工作。我已经使用 %norm 和 %norm% 尝试过了,并且在所有情况下似乎都能正确工作。 - Kyle Jones

2
我认为这个查询应该可以工作,尽管我没有在你的样本数据之外测试过它。
另外,你没有说明你使用的是什么数据库,我只是在 MS SQL 上尝试了一下,但是它应该很容易适应其他数据库,因为它只依赖于 charindex 和 left (或 substring) 函数,这些函数应该在大多数数据库中都可用。 SQL Fiddle MS SQL Server 2008 模式设置:
create table your_table (article varchar(10), tag varchar (20))
insert your_table values 
('Article 1','normal'),
('Article 2','apple'),
('Article 3','norm*'),
('Article 4','normalization'),
('Article 5','corvette')

查询1:
declare @str varchar(30) = 'normalization'

select t.article, tag 
from your_table t
left join (
    select 
       article, 
       left(tag, charindex('*', tag,0)-1) t, 
       charindex('*', tag,0)-1 as l 
    from your_table 
    where charindex('*', tag,0) > 0
    ) a
on t.article = a.article
where (tag = @str) or (left(@str, l) = t)
结果

|   ARTICLE |           TAG |
|-----------|---------------|
| Article 3 |         norm* |
| Article 4 | normalization |

查询2:
declare @str varchar(30) = 'normal'

select t.article, tag 
from your_table t
left join (
    select 
       article, 
       left(tag, charindex('*', tag,0)-1) t, 
       charindex('*', tag,0)-1 as l 
    from your_table 
    where charindex('*', tag,0) > 0
    ) a
on t.article = a.article
where (tag = @str) or (left(@str, l) = t)

结果:

结果

|   ARTICLE |    TAG |
|-----------|--------|
| Article 1 | normal |
| Article 3 |  norm* |

1
这就是我认为的唯一解决方案,但我想如果客户最终输入了大量数据,它会很慢。如果psadac在sqlite中不起作用,我将尝试这个答案。拥有多种选择总是很好的!谢谢。 - Kyle Jones

0
如果您使用SQL Server,可以这样做: 我的意思是, 如果以*结尾,则检查子字符串是否存在, 否则直接匹配
    SELECT * FROM Articles
    WHERE
    CASE WHEN RIGHT(Articles.Tag, 1) = '*'
        CHARINDEX(LEFT(Articles.Tag, LEN(Articles.Tag) - 1), GivenStr)
    ELSE
        Articles.Tag=GivenStr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接