1

In a php page, I have an array, similar to this:

$category = array(16, 22, 23);

Then I am doing a database query with a prepared statement. I would like to get all rows where the field category contains one of the values from that $category array and where price is lower than a value stored in the variable $price.

Among others I read the answers to this question and tried to use find_in_set() as described there (and at a lot of other places), but somehow I can't make it work within the prepared statement. I tried this:

/*  database connection "$db" is established beforehand and works  */

if($ps = $db->prepare("
   SELECT id, product, category, price 
   FROM products
   WHERE price <= ? and find_in_set(?, category)
   ORDER BY id") {
     $ps->bind_param("ds", $price, $category); 
     $ps->execute();
     $ps->bind_result($id, $name, $cat, $pr);
     while($ps->fetch()) {
       /* ...  echo the results .....  */
     }
    $ps->free_result();
    $ps->close();
 }

But I get an empty result.

If I try to use "dd" or "di" instead of "ds" in the bind_param() line, I do get results, but the wrong ones - I get all rows with category 1.

I also tried to use category IN ? instead of find_in_set(?, category), but that won't work either.

What can I do to make that work? Any help appreciated!

1

3 Answers 3

4

Two issues:

  • The list should be passed as second argument to find_in_set, so it should be:

    find_in_set(category, ?)
    
  • That argument should be of type string (comma separated values). So first convert your array to such a string with implode:

    $csv = implode(",", $category);
    

Code:

if($ps = $db->prepare("
   SELECT id, product, category, price 
   FROM products
   WHERE price <= ? and find_in_set(category, ?)
   ORDER BY id") {
     $csv = implode(",", $category);
     $ps->bind_param("ds", $price, $csv); 
     $ps->execute();
     $ps->bind_result($id, $name, $cat, $pr);
     while($ps->fetch()) {
       /* ...  echo the results .....  */
     }
    $ps->free_result();
    $ps->close();
}
Sign up to request clarification or add additional context in comments.

Comments

2

If you want to find values where $category belongs to a certain set try using IN. Just a note you cannot pass an array into a string like you have above.

Also don't forget to convert your array to a CSV string using implode

$category = array(16, 22, 23);
$cat_str = implode(",",$category);  //16,22,23

$ps = $db->prepare("
   SELECT id, product, category, price 
   FROM products
   WHERE price <= ? and category IN (?)
   ORDER BY id") {
$ps->bind_param("ds", $price, $cat_str); 

2 Comments

Hmm - that only returns the rows from the first value in the string. But the way @trincot describes it works for me, so I am all set. Still, thanks for taking the time to answer!
@Johannes I noted an error in my code above omitted the category before IN. I also used sqlFiddle to display results above. It's a good tool to use to have people help you. UNsure how you only got one result. :(
0

if i tried the same case , then i would probably have done it like this

SELECT id, product, category, price 
 FROM products
WHERE category = '16' || category = '22' || category = '23' and price < $price` 

i am assuming your $category array variable is fixed , it's not dynamically appending value .

I answered only your query part . i'd hope you have php coding convention idea rather than putting the entire statement in the if statement .

if still has anything to ask about , please go ahead

4 Comments

What is ||? And how would this work for any given array $category?
sir , || is equivalent to OR , and i probably i have mentioned above that i am assuming if he has finite array value , if his array grows dynamically then he might have to follow your way .,
True for the first point, unless the relevant configuration has been set for it to mean string-concatenation.
well, that's basically how I did it before I had to compare more than two values. But with more values that's getting rather complicated and additionally, my array/s now have different number/s of values, so I can't use that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.