是否有带AND逻辑的SQL WHERE IN语句?

时间:2018-02-03 23:51:01

标签: sql boolean-logic

我正在编写一些处理对象和标记云的代码,我正在努力想出一个通用的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'的切线属性,阻止它被包含在内。基本上它正在寻找与'红色'和'球'相匹配的物体,但没有其他属性,这不起作用)

那么,有什么建议吗?这是一个棘手的问题......

1 个答案:

答案 0 :(得分:2)

您使用group byhaving执行此操作。对于你的情况`:

select name
from @Table
where prop in ('red', 'ball')
group by name
having count(distinct prop) = 2;