我正在编写一些处理对象和标记云的代码,我正在努力想出一个通用的SQL搜索解决方案。
我希望允许用户能够在与对象关联的标签的UI中构建搜索。例如,用户可能会搜索标记为“ball”的所有对象,并搜索“red”以查找系统中的所有红色球。
以下是一些示例代码:
declare @Table table
(
[Name] varchar(50),
[Prop] varchar(50)
)
insert @Table (name,prop) values ('thing 1','ball')
insert @Table (name,prop) values ('thing 1','red')
insert @Table (name,prop) values ('thing 1','foo') -- tag not part of search
insert @Table (name,prop) values ('thing 2','ball')
insert @Table (name,prop) values ('thing 2','green')
insert @Table (name,prop) values ('thing 3','square')
insert @Table (name,prop) values ('thing 3','red')
insert @Table (name,prop) values ('thing 4','square')
insert @Table (name,prop) values ('thing 4','blue')
select distinct name from @Table
where prop in
(
'red','ball' -- returns thing 1, thing 2, thing 3
)
现在,一个精明的编码员会很快指出这会产生一个OR效果,抓住用'Green'和'Ball'标记的物体,这不是我们想要的。
显然我可以使用WHERE和AND来硬编码值。但是,我希望创建一个传递给表变量的SP,其中包含用户想要AND的所有标记,并且IN语法只允许我从该表参数中选择。
所以,我的问题是:是否有任何SQL语法或语句可以和任意数量的值?我不知道,我找不到任何有关快速搜索的内容。或者,有没有一种方法可以重组,以便我可以获得和AND结果的任意数量的变量?
我可以用生成动态SQL脚本的混乱代码来解决这个问题,但我需要性能。这不是一个真正可以接受的解决方案。
我曾尝试使用De Morgan的法律来判断我是否可以解决问题,但由于SQL逻辑的执行方式而失败。
select distinct name from @Table
where name not in
(
select name from @Table
where prop not in
(
'red','ball'
)
)
这会失败,因为它会查找ANDed标记,但会省略与标记不完全匹配的任何结果。 (事物1具有'foo'的切线属性,阻止它被包含在内。基本上它正在寻找与'红色'和'球'相匹配的物体,但没有其他属性,这不起作用)
那么,有什么建议吗?这是一个棘手的问题......
答案 0 :(得分:2)
您使用group by
和having
执行此操作。对于你的情况`:
select name
from @Table
where prop in ('red', 'ball')
group by name
having count(distinct prop) = 2;