views:

1839

answers:

8

Since I believe this should be a basic question I know this question has probably been asked, but I am unable to find it. I'm probably about to earn my Peer Pressure badge, but I'll ask anyway:

Is there a way in SQL Server that I am not aware of for using the wildcard character % when using IN.

I realize that I can use OR's like:

select *
from jobdetails
where job_no like '0711%' or job_no like '0712%'

and in some cases I can use a subquery like:

select *
from jobdetails
where job_no in (select job_no from jobs where job_id = 39)

but I'm looking to do something like the following:

select *
from jobdetails
where job_no in ('0711%', '0712%')

In this case it uses the percent sign as a character instead of a wildcard character so no rows are returned. I currently just use a bunch of OR's when I have to do this, but I know there has to be a better way. What method do you use for this?

+1  A: 

How about:

WHERE LEFT(job_no, 4) IN ('0711', '0712', ...)
Aaron Alton
I appreciate your response though and yes this works, but this is probably due to the simplifying of my example. I'd like something that didn't necessarily rely on the first 4 characters. I'm looking for something that would rely more on the wildcard. Thanks again though.
Dusty
+5  A: 

You could try something like this:

select *
from jobdetails
where job_no like '071[12]%'

Not exactly what you're asking, but it has the same effect, and is flexible in other ways too :)

Jeremy Smyth
This is pretty close to what I was looking for. Can the values between the quotes be expanded to for multiple values (Ex '071[10,22]%') and do you have a link that explains this in detail?
Dusty
@Dusty: No, '071[10,22]% will match any string '071x%, where x is one of 1 0 , or 2. Not looking for a 071 followed by either 10 or 22. See the patern section at: http://msdn.microsoft.com/en-us/library/ms179859.aspx
Shannon Severance
+1 although this is not exactly what I am looking for, but it is close and is helpful. Though it is probably the closest to what I was looking for I can't exactly mark it as the answer. Thanks
Dusty
Aww, so unfair!
Jeremy Smyth
HaHa, Sorry man. I'm going to post a follow-up question shortly that defines the issue which led me to this question. I figured if I could answer this question my problem would be resolved. Thanks again man for your response though.
Dusty
+1  A: 
SELECT c.* FROM(
SELECT '071235' AS token UNION ALL SELECT '07113' 
 UNION ALL SELECT '071343'
UNION ALL SELECT '0713SA'
UNION ALL SELECT '071443') AS c
JOIN (
SELECT '0712%' AS pattern UNION ALL SELECT '0711%' 
 UNION ALL SELECT '071343') AS d
ON c.token LIKE d.pattern

071235
07113
071343
AlexKuznetsov
Whoever downvoted, can you provide the reason for it?
AlexKuznetsov
No idea, but they better downvote mine too, then, because mine follows basically the same approach... except that you did yours in a single query whereas I did mine with some setup first.
GalacticCowboy
Three comments got downvoted within seconds of each other. I suspect we should all have answered "No.", which is the correct answer to the question, rather than expend effort in finding workable alternatives.
Jeremy Smyth
Rest assured it wasn't me. :)
Dusty
@galactic cowboy: But the correct answer is yes, not no. I edited the example to include one exact match, that is one pattern without %.
AlexKuznetsov
That was Jeremy. But the original question - as worded - can only be answered "no". There is no way to do it using "IN". A "yes" answer requires you to approach from a different direction.
GalacticCowboy
@galactic cowboy: I concur.
AlexKuznetsov
A: 

Peer Pressure is for removing an asnwer, does it apply to questions too? I worked soo hard to earn mine ;). Ans was actually a valid response lol.

Anyway, the IN operator is nothing but a fancy OR of '=' comparisons. In fact is soo 'nothing but' that in SQL 2000 there was a stack overflow bug due to expansion of the IN into ORs when the list contained about 10k entries (yes, there are people writing 10k IN entries...). So you can't use any wildcard matching in it.

Remus Rusanu
> 10K IN's ... *Shudder*
Gavin Miller
10k ANDs http://support.microsoft.com/kb/224581, 255 UNION ALL: http://support.microsoft.com/kb/892141
Remus Rusanu
I think your right now about the Peer Pressure badge. Hopefully I don't have to worry about it. :)
Dusty
A: 

You have the answer right there in your question. You cannot directly pass wildcard when using IN. However, you can use a sub-query.

Try this:

select *
from jobdetails
where job_no in (
select job_no
from jobdetails
where job_no like '0711%' or job_no like '0712%')
)

I know that this looks crazy, as you can just stick to using OR in your WHERE clause. why the subquery? How ever, the subquery approach will be useful when you have to match details from a different source.

Raj

Raj
Why would you need the subquery and instead just put the subquery or as the main query or?
Dusty
+3  A: 

How about something like this?

declare @search table
(
    searchString varchar(10)
)

-- add whatever criteria you want...
insert into @search select '0711%' union select '0712%'

select j.*
from jobdetails j
    join @search s on j.job_no like s.searchString
GalacticCowboy
And, as in AlexKuznetsov's answer, you can also do it in one query without the table variable or temp table.
GalacticCowboy
This is an interesting approach that I hadn't thought of. It probably runs faster than a bunch of OR's, but it'd probably be faster typing (copy and pasting) the OR's. I generally only do it if I need an ad hoc report for someone so generally the reason I want to do this is to save typing time.
Dusty
+1 on this approach as well although not exactly the answer I was looking for either.
Dusty
A: 

In Access SQL, I would use this. I'd imagine that SQLserver has the same syntax.

select * from jobdetails where job_no like "0711*" or job_no like "0712*"

PowerUser
I appreciate your response, but I'm trying to figure out a way to use the wildcard in an IN so that I don't have to do multiple OR's.
Dusty
A: 

Try this

select * from jobdetails where job_no between '0711' and '0713'

the only problem is that job '0713' is going to be return as well so can use '07299999999999' or just add "and job_no <> '0713'

Dan zamir

Dan Zamir