我有一个使用IN过滤器的查询,并且工作正常。我想知道是否有 就像通配符一样,不会过滤任何内容
<html>
<body>
<a href="https://www.w3schools.com/tags/tag_img.asp">
<img class="img" src="https://upload.wikimedia.org/wikipedia/commons/4/49/LACMTA_Square_Orange_Line.svg" alt="image at bottom">
</a>
</body>
</html>
上面的方法按需要工作,但是如果我不想按任何内容过滤并返回全部,该怎么办。我知道我可以创建第二个查询并删除IN子句,但是如果可能的话,从逻辑上来说,如果我可以检查是否存在过滤器值并且如果不存在过滤器值,则将其替换为通配符char
会更好。答案 0 :(得分:1)
IN
运算符不允许匹配通配符或部分值。实际上,它只是OR
逻辑运算符链的语法糖。
此查询:
SELECT 1 FROM SomeTable AS T
WHERE T.Column IN (1, 2, 3, 4)
与以下内容完全相同:
SELECT 1 FROM SomeTable AS T
WHERE
T.Column = 1 OR
T.Column = 2 OR
T.Column = 3 OR
T.COlumn = 4
这就是为什么将NULL
值和NOT IN
列表一起使用会使所有逻辑结果变为UNKNOWN
(因此被解释为false并且从不返回任何记录)的原因:
SELECT 1 FROM SomeTable AS T
WHERE T.Column NOT IN (1, 2, NULL, 4)
将会是:
SELECT 1 FROM SomeTable AS T
WHERE
NOT(
T.Column = 1 OR
T.Column = 2 OR
T.Column = NULL OR -- Always resolve to UNKNOWN (handled as false for the whole condition)
T.COlumn = 4
)
您可以通过几种选择有条件地应用IN
之类的过滤器:
在其他情况下使用OR
:
DECLARE @ApplyInFilter BIT = 0
SELECT 1 FROM SomeTable AS T
WHERE
(@ApplyInFilter = 1 AND T.Column IN (1, 2, 3, 4)) OR
@ApplyInFilter = 0
完全避免查询(必须重复整个语句):
DECLARE @ApplyInFilter BIT = 0
IF @ApplyInFilter = 1
BEGIN
SELECT 1 FROM SomeTable AS T
WHERE
T.Column IN (1, 2, 3, 4)
END
ELSE
BEGIN
SELECT 1 FROM SomeTable AS T
END
使用动态SQL有条件地省略过滤器:
DECLARE @ApplyInFilter BIT = 0
DECLARE @DynamicSQL VARCHAR(MAX) = '
SELECT 1 FROM SomeTable AS T '
IF @ApplyInFilter = 1
SET @DynamicSQL += ' WHERE T.Column IN (1, 2, 3, 4) '
EXEC (@DynamicSQL)
不幸的是,如果您打算拥有多个条件过滤器,最好的方法是使用动态SQL。这将是最难编写的代码,但性能最佳(有一些警告)。请阅读George的Menoutis链接,以充分了解每种方法的利弊。
答案 1 :(得分:0)
您可以利用不存在来获得所需的结果。根据我的理解,如果您有一个像Tom这样的名字,那么您只想要该行,如果您不想,则希望显示所有其他行。
select 1 as ID, 'Tom' as Name into #temp
union all
select 2 as ID, 'Ben' as Name union all
select 3 as ID, 'Kim' as Name
union all
select 4 as ID, 'Jim' as Name
This query will check if Tom exists then display only that row if not display all.
select * from #temp
where name = 'TOm' or not exists (select 1 from #temp where name = 'Tom')
Result from above query:
ID Name
1 Tom
通过删除Tom记录所在的行来对其进行测试。
Delete from #temp
where name = 'Tom'
如果运行相同的查询,则会得到以下结果。
select * from #temp
where name = 'TOm' or not exists (select 1 from #temp where name = 'Tom')
ID Name
2 Ben
3 Kim
4 Jim
答案 2 :(得分:0)
正如Dale Burrell所说,实现动态搜索条件(正是您的问题所在)的快速方法是将代码放入:
....and field=values or @searchThisField=0
另一种解决方案是动态sql。
我认为Erland Sommarskog's article是分析此特定主题的缩影。
答案 3 :(得分:0)
发出两个请求。这两个查询的性能将比单个通用查询的性能更好。您可以比较这些查询的执行计划。