Google Answers Logo
View Question
 
Q: SQL Query that checks for multiple values in a list ( No Answer,   14 Comments )
Question  
Subject: SQL Query that checks for multiple values in a list
Category: Computers > Programming
Asked by: biohaz-ga
List Price: $15.00
Posted: 15 Apr 2004 17:16 PDT
Expires: 16 Apr 2004 17:15 PDT
Question ID: 330983
I'm searching a database and need to check a range of selected values
against a field.

For example, I'm searching for 1,2,3.  My database looks something like this:

entry1 - 1,2,3,4,5,6
entry2 - 1,5
entry3 - 5,6,7,8
entry4 - 3

What I would want to do, based on the SQL I know, would be...

WHERE (('1','2','3') IN field)

...Or maybe this...

WHERE (field LIKE '%1%2%3%')

...and recieve entry1, entry2, and entry4 as a result set.

If I use WHERE (field IN ('1','2','3')) the only fields that are
returned are those that have ONLY 1, or ONLY 2, or ONLY 3 in them,
none that have a combo of those numbers and/or other numbers.

My question is two part, though basic I believe.

A) Is this possible?

B) If it is, then how? (you knew this one was coming)
Answer  
There is no answer at this time.

Comments  
Subject: Re: SQL Query that checks for multiple values in a list
From: pavlos-ga on 15 Apr 2004 18:25 PDT
 
1. Yes it's possible

2. The fast and easy way to do it is:
SELECT * FROM Table1 WHERE (field like '*1*') or (field like '*2*') or
(field like '*3*')

You should extend this query according to the requested values. Other examples:
WHERE (field like '*1*')
WHERE (field like '*1*') or (field like '*5*')

You may also consider this:
WHERE ((field like '*1*') or (field like '*3*')) and not (field like '*4*')
Subject: Re: SQL Query that checks for multiple values in a list
From: biohaz-ga on 15 Apr 2004 19:17 PDT
 
Thanks for the response...

The problem I'm having now with this solution is that if one of the
fields has 21 in it, a search for LIKE '%1%' returns the field with 21
as well as the field with 1.  Any idea how to deal with this
occurance, or do I really need to do this loop through code?
Subject: Re: SQL Query that checks for multiple values in a list
From: nelson-ga on 15 Apr 2004 21:16 PDT
 
Not knowing the specifics of your database, I'm guessing it is not
properly noramlized.  Normalization would greatly improve querying.
Subject: Re: SQL Query that checks for multiple values in a list
From: yeechern-ga on 15 Apr 2004 23:23 PDT
 
How about this:
WHERE (','+field+',' like '%,1,%') or (','+field+',' like '%,2,%') or
(','+field+',' like '%,3,%')
.. not an effective way but should be able to do what you need.
Subject: Re: SQL Query that checks for multiple values in a list
From: webdude99-ga on 16 Apr 2004 06:10 PDT
 
WHERE (field=1) or (field=2) or (field=3) etc.
Subject: Re: SQL Query that checks for multiple values in a list
From: scubajim-ga on 16 Apr 2004 09:10 PDT
 
Fix the database design.  This is a terrible design.
Subject: Re: SQL Query that checks for multiple values in a list
From: biohaz-ga on 16 Apr 2004 09:45 PDT
 
Okay I'm hearing from the masses that I've got a poorly designed
database... well sadly folks, as with most things, it is out of my
control...

This is what it is... A user has five fields that hold a list of
attributes within them... You mean to tell me that making a SEPERATE
field for each individual attribute would have been a better design? 
That would just increase my DB size, not help my solve my problem... 
I'd still have toi use multiple WHERE statements...

I believe I've gotten my answer, and that it is NOT possible to search
for a list of values within a field... thanks to those that actually
offered up some worthwhile assitance...
Subject: Re: SQL Query that checks for multiple values in a list
From: biohaz-ga on 16 Apr 2004 09:49 PDT
 
Also mentioned is normalization...  How would that help me here?  I
understand it will make everything faster but I'm not certain how it
would help me in this instance...
Subject: Re: SQL Query that checks for multiple values in a list
From: scubajim-ga on 16 Apr 2004 12:11 PDT
 
No, one would NOT make a field for each comma delimited entry.  One
would make a seperate table with two columns.  One column would relate
the original table and the other column would have an entry (eg 1). 
Then you would have multiple rows.

other table would look like:
  Key_to_parent_table   entry_values
   entry_1               1
   entry_1               2
   entry_1               3
   entry_2               2
   entry_3               1
   entry_3               4
...

Then the SQL statement would be fairly simple.(and a much better design)
Subject: Re: SQL Query that checks for multiple values in a list
From: stephenvakil-ga on 16 Apr 2004 14:16 PDT
 
But regardless you can do
where (field like '1,%' or field like '%,1,%' or field like '%,1')

I BELIEVE that will work, not sure.

I will definitely agree that this is a terrible design.
Subject: Re: SQL Query that checks for multiple values in a list
From: biohaz-ga on 16 Apr 2004 14:41 PDT
 
*little light bulb goes off* Okay, now I totally see what you mean
scubajim... hrmmmmm... I might be able to get the design changed... 
Alright, thanks alot for the assitance :)
Subject: Re: SQL Query that checks for multiple values in a list
From: fischer_msft-ga on 16 Apr 2004 15:20 PDT
 
Here's my $.05

As everyone has stated, this does appear to be very bad db design.  If
you'd like to learn more about the different degrees of database
design here is a link that should help.

http://www.4guysfromrolla.com/webtech/042699-1.shtml

To answer your question, this is the approach I would use (if I were
forced by a design that was out of my control).  I'm assuming you're
using SQL Server which supports table valued functions.

First, here is a function that will take your list of numbers and
expand them into rows using a delimiter of your choice(the results
will have one row for each value in your list).  Execute and
understand what this function does prior to proceeding with my
suggestion.

IF ISNULL(OBJECTPROPERTY(OBJECT_ID('dbo.fn_Split'), 'IsTableFunction'), 0) = 1
   DROP FUNCTION dbo.fn_Split
GO

CREATE FUNCTION dbo.fn_Split (
   @vcrText  varchar(8000)
 , @vcrDelim varchar(20) = ' '
)
RETURNS @retArray TABLE (
   RowIndex smallint Primary Key
 , Value    varchar(8000)
)
AS
BEGIN
   DECLARE @intIndex         smallint
         , @vcrValue         varchar(8000)
         , @intPlacement     smallint
         , @intLastPlacement smallint
         , @intStrike        smallint
         , @intTextLength    tinyint
         , @intDelimLength   tinyint
   
   IF @vcrDelim = 'Space'
      SET @vcrDelim = ' '
   IF @vcrDelim = 'Empty' OR @vcrDelim = ''
      SET @vcrDelim = ' '
   
   SELECT @intIndex         = 1
        , @intPlacement     = 0
        , @intLastPlacement = 0
        , @vcrText          = LTRIM(RTRIM(@vcrText))
        , @intTextLength    = DATALENGTH(@vcrText)
        , @intDelimLength   = DATALENGTH(@vcrDelim)
   
   WHILE (@intPlacement < @intTextLength)
   BEGIN
      -- If you can find the delimiter in the text, retrieve the first element and
      -- insert it with its index into the return table.
 
         SET @intLastPlacement = @intPlacement + 1
         IF @vcrDelim Is Null
            SET @intPlacement = @intLastPlacement + 1
         ELSE
         BEGIN
            SET @intPlacement = CHARINDEX(@vcrDelim, @vcrText, @intLastPlacement)
            IF (@intPlacement = 0)
               SET @intPlacement = @intTextLength + 1
         END
         
         SET @vcrValue = SUBSTRING(@vcrText, @intLastPlacement,
@intPlacement - @intLastPlacement)
         INSERT @retArray
         VALUES (@intIndex, @vcrValue)
         
         SET @intIndex = @intIndex + 1
   END

   RETURN
END
GO

SELECT *
FROM dbo.fn_Split('1,2,3', ',')
GO

Now that you understand the results of this functions lets tie it in
with your question.  You would like results from a table based on
whether one or more delimited values in a list match one or more
values in a varchar field within your table.  I have provided a table
valued function to enumerate a list of delimited values in a varchar
out to rows.  Now that we have rows for each value we can try to match
those values against values within your field using a join and the
Like operator as suggested by prior comments.  Here is my test script
that does exactly as I've described. You'll notice I have two select
statements.  The first select statement returns all rows with no
aggregation.  Now that we're joining our base table against the
enumerated list of values we supplied to the table-valued function, we
end up with multiple rows (one row for each list value that matches
the fields).  My second SELECT statement remedies this issue by
performing a DISTINCT on the results (which could also be done with
GROUP BY t.Entry).  Note my INNNER JOIN methodolgy.  One (t.Entry Like
s.Value + ',%') tests whether the value matches the first value in the
entry field and the second (t.Entry Like '%,' + s.Value + ',%') tests
whether the value matches a value in the list and final (t.Entry Like
'%,' + s.Value) test whether the value matches the last value in the
entry field.

CREATE TABLE #TestEntry (
   Entry varchar(25)
)
GO

INSERT INTO #TestEntry
VALUES('1,2,3,4,5,6')
INSERT INTO #TestEntry
VALUES('1,5')
INSERT INTO #TestEntry
VALUES('5,6,7,8')
INSERT INTO #TestEntry
VALUES('3')
GO

SELECT t.Entry, s.Value
FROM #TestEntry t
INNER JOIN dbo.fn_Split('1,2,6', ',') s
ON t.Entry Like s.Value + ',%'
OR t.Entry Like '%,' + s.Value + ',%'
OR t.Entry Like '%,' + s.Value

SELECT DISTINCT t.Entry
FROM #TestEntry t
INNER JOIN dbo.fn_Split('1,2,6', ',') s
ON t.Entry Like s.Value + ',%'
OR t.Entry Like '%,' + s.Value + ',%'
OR t.Entry Like '%,' + s.Value
GO

DROP TABLE #TestEntry
GO

The reason I suggest using the table valued function is that the code
will accomodate any number of values in your list to match as opposed
to the prior suggestions which have a limit of 'hard coded' values.

HTH
Fischerman
Subject: Re: SQL Query that checks for multiple values in a list
From: fischer_msft-ga on 16 Apr 2004 15:23 PDT
 
Typo-

As everyone has stated, this does appear to be very bad db design.  If
you'd like to learn more about the different degrees of database
design here is a link that should help.

Revision:
As everyone has stated, this does appear to be very bad db design.  If
you'd like to learn more about the different degrees of database
NORMALIZATION here is a link that should help.
Subject: Re: SQL Query that checks for multiple values in a list
From: biohaz-ga on 16 Apr 2004 15:49 PDT
 
*blinks*

Wow... That rocks... I'll reply in depth once I've played with this a
bit but that was exactly the type of functionality I was looking
for... How do I make a comment the answer to a question?  Cause you
just nailed it...

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy