我很想有一个T-SQL语句像下面...CASE语句切换WHERE条件
SELECT [field]
FROM [table]
WHERE CASE @flag
WHEN 1 THEN col1 = @value
ELSE col2 = @different_value
END
问题的关键是我想提出一个标志,在我的功能使用不同的where子句中相同的查询。我只是无法让它工作。这可能吗?
我很想有一个T-SQL语句像下面...CASE语句切换WHERE条件
SELECT [field]
FROM [table]
WHERE CASE @flag
WHEN 1 THEN col1 = @value
ELSE col2 = @different_value
END
问题的关键是我想提出一个标志,在我的功能使用不同的where子句中相同的查询。我只是无法让它工作。这可能吗?
这是否适合您?
Where (@flag = 1 and col1 = @value) or (@flag != 1 and col2 = @different_value).
随着mySQL的声明应该工作,因为mySQL支持二进制表达式。
所以你一定要试试这个
SELECT [field]
FROM [table]
WHERE CASE @flag
WHEN 1
THEN case when col1 = @value then 1 else 0 end
ELSE case when col2 = @different_value then 1 else 0 end
END = 1
这是不是很不错的可读性。请注意性能问题,因为优化器可能在这里挣扎。
优化器可能在这里挣扎。使它工作并使其快速工作(使用索引)通常是完全不同的。 – 2010-07-15 14:57:33
基于给定参数的动态改变搜索是一个复杂的问题,并做了一个又一个的方式,即使只有极轻微的不同,可以有巨大的性能影响。关键是要使用索引,忽略紧凑的代码,不要担心重复的代码,你必须制定一个好的查询执行计划(使用索引)。
阅读并考虑所有的方法。你最好的方法将取决于您的参数,你的数据,你的模式,你的实际使用情况:
Dynamic Search Conditions in T-SQL by by Erland Sommarskog
The Curse and Blessings of Dynamic SQL by Erland Sommarskog
这将产生最佳的执行计划:
IF @flag=1
BEGIN
SELECT
[field]
FROM [table]
WHERE col1 = @value
END
ELSE
BEGIN
SELECT
[field]
FROM [table]
WHERE col2 = @different_value
END
然而,如果你必须有一个单一的查询,这是你使用索引的最佳选择
SELECT
[field]
FROM [table]
WHERE @flag=1
AND col1 = @value
UNION ALL
SELECT
[field]
FROM [table]
WHERE @flag!=1
AND col2 = @different_value
您还可以使用布尔逻辑:
SELECT blah FROM myTable WHERE (@i IS NULL OR AnotherCondition)
如何简单;
WHERE
(@flag = 1 AND col1 = @value)
OR
(@flag = 2 AND col2 = @different_value)
...
非常好。第一遍,看起来像是有效的。我会继续测试,但我认为这是一个过程。也很简单。谢谢! – Peter 2010-07-15 15:09:02
这里没有索引使用的机会,除非你包含OPTION(RECOMPILE)并且在SQL Server 2008的某个版本上运行,请参阅我的答案中的链接[A Service of Service Packs and Cumulative Updates]( http://www.sommarskog.se/dyn-search-2008.html#SPandCUs)。此链接解释了2008年的最新版本如何在考虑到局部变量的运行时间值的情况下重新编译查询。如果@flag不是1,并且如果它是1,那么可以在查询之外优化“(@flag = 1和col1 = @value)”之类的内容,然后优化为“col1 = @ value” – 2010-07-15 15:09:25
我正在运行SQL Server 2005,所以我猜它不会优化。 – Peter 2010-07-15 15:23:03