2010-05-11 66 views
1

我有一个关于where语句中的case语句和null的问题。SQL Where Where

我要做到以下几点:

Declare @someVar int = null 

select column1 as a from 
TestTable t 
where column1 = case when @someVar is not null then @someVar else column1 end 

这里的问题是:

比方说@someVar为空。我们还要说TestTable中的column1具有NULL列值。然后,在case语句中我的条件t = t将始终评估为false。

我基本上只是希望能够根据@someVar的值(如果提供的话)有条件地过滤列。任何帮助?

回答

2
  • 如果@someVar IS NULL总是返回该行。
  • 如果@someVar IS NOT NULLcolumn1 = @someVar返回该行。
  • 否则不要返回该行。

那么试试这个:

SELECT column1 
FROM TestTable t 
WHERE @someVar IS NULL OR column1 = @someVar 

要测试这个表达式的作品尝试插入一些测试值到一个表,然后获取所有行,其中b为空或a等于b

CREATE TABLE Table1 (a VARCHAR(20) NULL, b VARCHAR(20) NULL); 
INSERT Table1 (a, b) VALUES 
(NULL, NULL), 
('Foo', NULL), 
(NULL, 'Foo'), 
('Foo', 'Foo'), 
('Bar', 'Foo'); 

SELECT * 
FROM Table1 
WHERE b IS NULL OR a = b 

结果:

a  b 
NULL NULL 
Foo NULL 
Foo Foo 
+0

我这样做是因为上面的生成语法错误(我在SQL Server) “其中@someVar为NULL或列1 = @someVar” 这一工程!你在做同样的事情吗? – needshelp 2010-05-11 00:32:58

+0

不应该是OR column1 = COALESCE(@someVar,0) – 2010-05-11 00:39:06

+0

@needshelp:你说得对。我已经更新了我的答案。 – 2010-05-11 06:17:50

2

虽然条件筛选是主流模式,但我敦促您重新考虑您的意图。将多个查询压缩为单个形状的次数越多,就越会干扰优化程序找出查询所做的操作的能力,并且生成的查询执行计划的可能性越低。

在这种情况下,如果不检查@somevar,优化程序无法判断column1是否为过滤器。那么应该使用column1上的索引还是不使用?

+0

你还会怎么做?这是一个艰难的地方在 – 2010-05-11 00:53:20

+1

压缩多个查询到一个单一的替代方案,是表示多个查询 - 单独到数据库。如果您将查询视为转换为(单一)执行计划的文本,那么您就明白了。如果你发现你确实需要一个可组合的块来让你的查询出来(实际上,谁也没有),我推荐一个ORM,比如LinqToSql。 ORM在客户端组成查询文本,数据库只能看到预期的查询 - 而不是一堆变量。 – 2010-05-11 01:08:08