If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Database Server Software > MySQL > MySQL IN clause help

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 09-20-09, 11:16
ozzii ozzii is offline
Registered User
 
Join Date: Mar 2007
Posts: 194
MySQL IN clause help

Hi

I have the following stored procedure:

Code:
CREATE PROCEDURE get_customers(IN inCustomerIdList VARCHAR(100))
BEGIN

  SELECT first_name, last_name, email FROM tbl_customers  
  WHERE customer_id IN (inCustomerIdList);

END$$
The above should retrieve all customers whose id appears in the inCustomerIdList variable. inCustomerIdList is a string variable e.g. "8,9,5,6,10".

However the above procedure only retreives the customer which has the id number of the first id in the above string. Now I know i would have to put each id in quotes to retrieve all customers in this list i.e ('8','9','5','6','10').

Is there any way for me to convert the original string variable so that i can pass it in just like this: (8,9,5,6,10) or is there a MySQL function to concat apostraphes to each id?
Reply With Quote
  #2 (permalink)  
Old 09-20-09, 14:27
mike_bike_kite mike_bike_kite is offline
vaguely human
 
Join Date: Jun 2007
Location: London
Posts: 2,519
I suppose it's not worth me telling you why your general design is poor but to get you out of a fix you could try something like :
Code:
CREATE PROCEDURE get_customers(IN inCustomerIdList VARCHAR(100))
BEGIN

  SELECT first_name, last_name, email FROM tbl_customers  
  WHERE concat( ',',inCustomerIdList,',' ) like concat( '%,',customer_id,',%' );

END$$
Reply With Quote
  #3 (permalink)  
Old 09-20-09, 15:10
ozzii ozzii is offline
Registered User
 
Join Date: Mar 2007
Posts: 194
Quote:
Originally Posted by mike_bike_kite
I suppose it's not worth me telling you why your general design is poor but to get you out of a fix you could try something like :
Code:
CREATE PROCEDURE get_customers(IN inCustomerIdList VARCHAR(100))
BEGIN

  SELECT first_name, last_name, email FROM tbl_customers  
  WHERE concat( ',',inCustomerIdList,',' ) like concat( '%,',customer_id,',%' );

END$$

Thanks for the tip but i've managed to find an even easier solution by using the FIND_IN_SET clause. By the way why is the design poor?
Reply With Quote
  #4 (permalink)  
Old 09-20-09, 17:54
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,534
because FIND_IN_SET, and any other solution such as the more complex LIKE one, do not scale

unable to utilize an index, they get slower and slower as the number of rows increases

plus, updates and deletes require egregiously complex application logic
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #5 (permalink)  
Old 09-21-09, 05:55
ozzii ozzii is offline
Registered User
 
Join Date: Mar 2007
Posts: 194
Quote:
Originally Posted by r937
because FIND_IN_SET, and any other solution such as the more complex LIKE one, do not scale

unable to utilize an index, they get slower and slower as the number of rows increases

plus, updates and deletes require egregiously complex application logic

so what would be a better solution? lets say I append each id number in quotes via the application logic and then use the IN clause - the IN clause would still have the same scalability issues?

Last edited by ozzii; 09-21-09 at 08:02.
Reply With Quote
  #6 (permalink)  
Old 09-21-09, 06:19
mike_bike_kite mike_bike_kite is offline
vaguely human
 
Join Date: Jun 2007
Location: London
Posts: 2,519
You should have your list of customer ids in a table as separate rows. This will be more expandable and much faster as it can use the indexes. I don't know what your database holds so I can't give you a complete answer but look up first normal form for more info. As it stands your system may work fine but if the system expands and you get more users and customers then you'll soon run into problems.
Reply With Quote
  #7 (permalink)  
Old 09-21-09, 08:01
ozzii ozzii is offline
Registered User
 
Join Date: Mar 2007
Posts: 194
Quote:
Originally Posted by mike_bike_kite
You should have your list of customer ids in a table as separate rows. This will be more expandable and much faster as it can use the indexes. I don't know what your database holds so I can't give you a complete answer but look up first normal form for more info. As it stands your system may work fine but if the system expands and you get more users and customers then you'll soon run into problems.
the customer ids are indeed held in a table and they form the primary key for that table. However if i want to run a query to retrieve some details e.g. firstname, lastname, email etc for a list of customers and all i have is there id numbers eg 101, 102, 109, 111 ... In this instance how would you run a query to retrieve this information? Using the IN or FIND_IN_SET seem like the most obvious to me unless i ran invidual select queries on each id number however that would take forever if i have list of hundred ids.
Reply With Quote
  #8 (permalink)  
Old 09-21-09, 12:30
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,534
in that case, IN ( list ) is exactly what you want here
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On