tags:

views:

81

answers:

3
+1  Q: 

SQL Where question

Hi all,

I have a question about case statements and nulls in a where clause.

I want to do the following:

Declare @someVar int = null

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

Here is the problem:

Let's say @someVar is null. Let's also say that column1 from TestTable t has NULL column values. Then, my condition t = t in the case statement will always evaluate to false.

I basically just want to be able to conditionally filter the column based on the value of @someVar if it's provided. Any help?

A: 

Maybe looking into COALESCE will help you.

Lars Andren
+2  A: 
  • If @someVar IS NULL always return the row.
  • If @someVar IS NOT NULL and column1 = @someVar return the row.
  • Otherwise don't return the row.

So try this:

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

To test that this expression works try inserting some test values into a table and then fetch all the rows where b is NULL or a is equal to 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

Result:

a     b
NULL  NULL
Foo   NULL
Foo   Foo
Mark Byers
I did this since the above generates a syntax error(I'm in SQL Server)"where @someVar is NULL or column1 = @someVar"That works! Is that the same thing you're doing?
needshelp
Shouldn't it be OR column1 = COALESCE(@someVar, 0)
Joe Philllips
@needshelp: You are right. I've updated my answer.
Mark Byers
+2  A: 

While conditional filtering is a mainstream pattern, I urge you to reconsider your intent. The more you compress multiple queries into a single shape, the more you interfere with the ability of the optimizer to figure out what your query does, and the more likely the resulting query execution plan will be poor.

In this case, the optimizer can't tell whether column1 is a filter or not without inspecting @somevar. So should an index on column1 be used or not?

David B
How else would you do it though? It's a tough spot to be in
Joe Philllips
The alternative to compressing multiple queries into a single one, is to express the multiple queries - seperately to the database. If you think of a query as text that is transformed into a (single) execution plan, you've got the idea. If you find you really need a composable set of blocks to make your query out of (and really, who doesn't), I recommend an ORM, such as LinqToSql. ORM's compose the query text on the client side and the database only sees the intended query - instead of a slew of variables.
David B