开发者

SQL Case statement to check for NULLS and Non-existent records

I am doing a join between two tables and want to select the columns based on whether they have a record or not. I'm trying to avoid having multiple of the same field and am trying to condense them into single columns. Something like:

Select 
    id = (CASE WHEN a.id IS NULL THEN b.id ELSE a.id END),
    name = (CASE WHEN a.name IS NULL THEN b.name ELSE a.name END)
From Table1 a
Left Join Table2 b
On a.id = b.id
Where a.id = @id

I'd like id to populate from Table1 if a record exists, but if not pull from Table2. The previous code returns no records because there are no NULL values in Table1 so my question is how do I run a check to see if any records even exist? Also if anyone knows of a better way to accomplish what I am trying to do I appreciate guidance and constructive criticism.

EDIT

It looks like COALESCE will work for what I'm trying to accom开发者_如何学JAVAplish. I'd like to give a little more info on exactly what I am working with and get some advice on whether I am using the best method.

I have a bloated table Table2 and it is in production. I'm working on building new web applications for this system but can't justify a complete database redesign so I am trying to do one "on the fly". I've created a new table Table1 and I am writing stored procedures for the following methods Get(Select), Set(Update), Add(Insert), Remove(Delete). This way, to my code, it will seem that I am working with a single table that is not bloated. My code will simply call one of the SP methods and then the stored procedure will handle the data between the old table and the new. I am currently working on the Get method and I need to check the old table Table2 for a record if it doesn't exist in Table1. Thanks to the suggestions here my query currently looks like this:

Select
    id = coalesce(a.id, b.student_number),
    first_name = coalesce(a.first_name, b.first_name),
    last_name = coalesce(a.last_name, b.last_name),
    //etc
From Table1 a
Full Outer Join Table2 b
On a.id = b.student_number
Where (a.id = @id Or b.student_number = @id)

This works for what I'm trying to accomplish, I'd like to throw it out there to the experienced crowd for any tips or suggestions if there are better or more correct ways to go about this.

Thanks


I suspect your problem may come from doing a left join. Try again using a full outer join, like this:

Select 
    id = coalesce(a.id, b.id),
    name = coalesce(a.name, b.name)
From Table1 a
full outer Join Table2 b
On a.id = b.id
Where a.id = @id


Select id = coalesce(a.id, b.id), 
    name = coalesce(a.name, b.name)
From Table2 b 
Left Join Table1 a On a.id = b.id 
Where b.id = @id 

You may need to use ISNULL or CASE instead of COALESCE depending on your database platform.


First, you don't need a case statement for that:

Select ISNULL(a.id,b.id) AS id, ISNULL(a.name,b.name) AS name,
From Table1 a
Left Join Table2 b
On a.id = b.id
Where a.id = @id

Second, if I get it right, the id field can contain nulls, and in that case you are screwed. I mean, the ID is a unique value that identify a row, if it can be null, you can't identify that row.

But if what you want is getting records from Table1 and Table2 and avoid duplicates, a simple UNION will work fine, since it discards duplicates:

select id, name
from Table1
where id = @id

union

select id, name
from Table2
where id = @id


You could do something like:

select id, name from Table1 a where a.id not in (select id from Table2) UNION select id, name from Table2 b

This would give you all the records from table1 that didn't have a corresponding match in table2 plus all of table2's records. The union would then combine the results.


In your first CASE statement, a.id and b.id will always be same value, except for instances in which a.id has a value and b.id generates a NULL value because of the LEFT JOIN. There will never be a row in the result set with a NULL a.id value and a non-NULL b.id value. You could just use a.id for this column.

For the second CASE statement, you may find the name column in either or both tables with a value (and, of course, the values may be different). You said you want to "condense" the these column values; the SQL function for that is COALESCE:

 COALESCE(a.id, b.id)

which returns the first non-NULL value (a.id if it isn't NULL, otherwise b.id). It won't tip you off to different names in the two tables.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜