8

I have a complex query which joins more than 7 tables. After the joins, I would like to filter the result of my query .

Here is something that I observed.

When I do a where clause

where X.Name != 'xxx'
and  XY.Product != 1

I get the filtered results , but all the null values for the X.Name and XY.Product also disappear from my result. I would like to retain the null values.

I also tried :

and X.Name != 'xxx'
and  XY.Product != 1

I removed the where clause totally and put in an and , but I dont see the filtering at all by this approach.

Is there a way I can filter my results without losing the null values ??

3
  • Null has interesting equality properties. Try switching too AND NOT X.Name == 'xxx'. Commented Sep 23, 2013 at 16:40
  • 1
    Have you verified that you have all the NULLs after your joins? Common mistake is when doing multiple joins is to do INNER JOIN after OUTER JOIN. This could negate OUTER JOIN effect Commented Sep 23, 2013 at 16:41
  • Suspect you have outer joins. Checking for = or != in the where kills the outer. See solution from das. Commented Sep 23, 2013 at 16:49

5 Answers 5

10

Try something like:

where (X.Name <> 'xxx' or X.Name is null)
  and (XY.Product <> 1 or XY.Product is null)

Since, by definition NULL is an unknown value (bit simplified but OK for this explanation), it will neither equal or not equal a given value - that's why the IS NULL is required here.

Sign up to request clarification or add additional context in comments.

Comments

4

This quote is taken from 70-461 training kit.

"T-SQL—again, based on standard SQL—implements only one general purpose mark called NULL for any kind of missing value. This leads to three-valued predicate logic."

Therefore, here are the three logic conditions you can have.

1 - Value matches condition
2 - Value does not match condition
3 - Value is missing.

Here is some sample code to play around with.

-- Create sample table
create table #products
( 
  my_id int identity (1, 1),
  my_name varchar(16)
);

-- Load with sample data
insert into #products (my_name) values
(NULL),
('iPad'),
('Windows Surface');

-- Show the data
select * from #products

-- Show just ipads
select * from #products where my_name = 'iPad'

-- Show just surfaces
select * from #products where my_name <> 'iPad'

-- Show ipads & unknowns
select * from #products where my_name = 'iPad' or my_name is null

Here is the output from the last three select statements.

enter image description here

Comments

0

Why not use this: where isnull(X.Name,'') != 'xxx' and isnull(XY.Product,0) != 1

Comments

0
SELECT X.NAME,XY.PRODUCT FROM

(SELECT ID,NAME FROM TABLE_X WHERE NAME!=1)X
OUTER JOIN
(SELECT ID,PRODUCT FROM TABLE_XY WHERE PRODUCT!=1)XY
ON X.ID=XY.ID

Comments

0
where (X.Name != 'xxx' or X.name Is Null)
and  (XY.Product != 1 or XY.Product Is Null)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.