views:

38

answers:

3

Is there a way to retrieve all the data from an IN clause?

Let's assume my table got (ID,Name):

0 Banana
1 Mango
2 Papaya
3 Lemon

and my query:

SELECT * FROM Fruits WHERE Name IN (Banana,Mango,Orange)

I Want 'Orange' to return, with an empty ID (since there's no register). How to do this?

+5  A: 

You can't use the IN clause for this. You would need to get the target fruits into a table that you can outer join against.

SELECT ...
FROM 
(SELECT 'Banana' AS fruit UNION ALL SELECT 'Mango' UNION ALL SELECT 'Orange') f 
LEFT JOIN Fruits ON Fruits.Name = f.fruit

Or Option 2 (as long as your list is <= 8000 characters). Create a UDF like the one here (but using varchar(8000) instead of varchar(max)). Then use it as follows.

SELECT ...
FROM dbo.fnSplitStringList('Banana,Mango,Orange') f 
LEFT JOIN Fruits ON Fruits.Name = f.StringLiteral
Martin Smith
+1 - Better than the one I was trying to write :)
JNK
Alright, lets assume i got over 1500 registers, theres a better way to do this?
alex
@alex - You could pass them in as a comma delimited list and use a split table valued function (e.g. [dbo.fnSplitStringList](http://www.sqlusa.com/bestpractices/training/scripts/userdefinedfunction/) here) that you then join against. Or pass them in as XML possibly. Not sure what SQL2000 support is like for that option.
Martin Smith
Nah, sql2000 really sucks, i wish i was on Oracle :| Anyone else?
alex
How would you do this on Oracle?
Martin Smith
I would create a temp table, i just dont have enough permissions on this god damned sql server. heh.
alex
@alex - You should be able to create a table variable in SQL Server 2000 regardless of your permissions. (Possibly a `#temp` table as well - I think anyone can create those)
Martin Smith
A: 

Right join by name, but you need a separate table with names.

gandjustas
A: 

If you are doing it once, I wrote a program, it simplifies creating the "IN" clause, here: InClauseCreator. If, however, you are doing it regularly, then you'd be better off importing data into a temp table and then doing a left join, close to what Martin Smith suggested.

Eugene