2010-07-15 101 views
1

我很想有一个T-SQL语句像下面...CASE语句切换WHERE条件

SELECT [field] 
FROM [table] 
WHERE CASE @flag 
     WHEN 1 THEN col1 = @value 
     ELSE col2 = @different_value 
     END 

问题的关键是我想提出一个标志,在我的功能使用不同的where子句中相同的查询。我只是无法让它工作。这可能吗?

回答

4

这是否适合您?

Where (@flag = 1 and col1 = @value) or (@flag != 1 and col2 = @different_value). 
+0

非常好。第一遍,看起来像是有效的。我会继续测试,但我认为这是一个过程。也很简单。谢谢! – Peter 2010-07-15 15:09:02

+0

这里没有索引使用的机会,除非你包含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

+0

我正在运行SQL Server 2005,所以我猜它不会优化。 – Peter 2010-07-15 15:23:03

1

随着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 

这是不是很不错的可读性。请注意性能问题,因为优化器可能在这里挣扎。

+0

优化器可能在这里挣扎。使它工作并使其快速工作(使用索引)通常是完全不同的。 – 2010-07-15 14:57:33

1

基于给定参数的动态改变搜索是一个复杂的问题,并做了一个又一个的方式,即使只有极轻微的不同,可以有巨大的性能影响。关键是要使用索引,忽略紧凑的代码,不要担心重复的代码,你必须制定一个好的查询执行计划(使用索引)。

阅读并考虑所有的方法。你最好的方法将取决于您的参数,你的数据,你的模式,你的实际使用情况:

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 
+0

我同意。我会把这些放在“必读”堆栈中。谢谢回复。 – Peter 2010-07-15 15:09:40

+0

它“有”是一个查询,因为我将它用作接收@flag参数的函数。我将在where子句中测试联合而不是OR。这是一个相对较小的查询,所以我不知道它会产生巨大的差异,但很有必要了解使用不同数据集的潜在未来问题。感谢所有的帮助! – Peter 2010-07-15 15:25:26

0

您还可以使用布尔逻辑:

SELECT blah FROM myTable WHERE (@i IS NULL OR AnotherCondition) 
0

如何简单;

WHERE 
    (@flag = 1 AND col1 = @value) 
OR 
    (@flag = 2 AND col2 = @different_value) 
...