31

I know how to perform an SQL LIKE % query for a single value like so:

SELECT * FROM users WHERE name LIKE %tom%;

but how do I do this if the search terms for my LIKE comes from an array? For example, let's say we have an array like this:

$words = array("Tom", "Smith", "Larry");

How do I perform my SQL LIKE % to search for the words in my array like:

SELECT * FROM users WHERE name LIKE %[each_element_from_my_array]%

WITHOUT putting the whole query inside a foreach loop or something

EDIT : I forgot to mention that I'm doing this in cakePHP inside the conditions of the cakePHP find('all') method, so that complicates things a little bit.

Thanks

1
  • Your question has at least 5 votes for the like-operator tag. Could I kindly request that you suggest sql-like as a synonym? Commented Apr 2, 2013 at 18:41

9 Answers 9

35
$sql = array('0'); // Stop errors when $words is empty

foreach($words as $word){
    $sql[] = 'name LIKE %'.$word.'%'
}

$sql = 'SELECT * FROM users WHERE '.implode(" OR ", $sql);

Edit: code for CakePHP:

foreach($words as $word){
    $sql[] = array('Model.name LIKE' => '%'.$word.'%');
}

$this->Model->find('all', array(
    'conditions' => array(
        'OR' => $sql
    )
));

Read up on this stuff: http://book.cakephp.org/1.3/en/view/1030/Complex-Find-Conditions

Sign up to request clarification or add additional context in comments.

4 Comments

my thought exactly. nice answer! just need to be careful when having an empty array which would cause SQL error...
I think OR 0 would do just fine... ;)
This will work, but how do I do this inside the cakePHP find('all') function (See edit)
I know this is old, but just struck me how this would be open to sql injection - what with security being a hot topic atm thought I'd raise it
32

In case of standard SQL, it would be:

SELECT * FROM users WHERE name LIKE '%tom%' 
                       OR name LIKE '%smith%' 
                       OR name LIKE '%larry%';

Since you're using MySQL you can use RLIKE (a.k.a. REGEXP)

SELECT * FROM users WHERE name RLIKE 'tom|smith|larry';

3 Comments

RLIKE happened to be an absolutely great solution for me, thanks!! ;)
my column 'name' needs to be wrapped in 'lower' function, does it make the query slow on multiple 'or's and 'like's?
RLIKE saved the day. Thanks a bunch, kind internet stranger
4

You can't. It'll have to be a chained field like %..% or field like %..% or .... A where ... in clause only does extract string matches, with no support for wildcards.

Comments

3

try using REGEXP

SELECT * FROM users where fieldName REGEXP 'Tom|Smith|Larry';

Comments

0

i just took the code of 472084.

$sql = array('0'); // Stop errors when $words is empty

foreach($words as $word){
    $sql[] = 'name LIKE %'.$word.'%'
}

$sql = 'SELECT * FROM users WHERE '.implode(" OR ", $sql);

For my self, i had to modify it because it's returned me an error SQL. I Post it for people who gonna read the thread.

foreach($words as $word){
    $sql[] = 'name LIKE \'%'.$word.'%\'';
}

$sql = 'SELECT * FROM users WHERE '.implode(" OR ", $sql);

The difference between them is about quote, my mysql DB said there is a problem ! so i had to escape quote from $sql[] = 'name LIKE %'.$word.'%' and now it's work perfectly.

Comments

0

Blockquote

/** * Implode a multidimensional array of values, grouping characters when different with "[]" block. * @param array $array The array to implode * @return string The imploded array */ function hoArray2SqlLike( $array ) { if ( ! is_array( $array ) ) return $array;

$values  = array();
$strings = array();

foreach ( $array as $value )
{
    foreach ( str_split( $value ) as $key => $char )
    {
        if ( ! is_array( $values[ $key ] ) )
        {
            if ( isset( $values[ $key ] ) )
            {
                if ( $values[ $key ] != $char )
                {
                    $values[ $key ]     = array( $values[ $key ] );
                    $values[ $key ][]   = $char;
                }
            }
            else
                $values[ $key ] = $char;
        }
        elseif ( ! array_search( $char , $values[ $key ] ) )
            $values[ $key ][] = $char;
    }
}

foreach ( $values as $value )
{
    if ( is_array( $value ) )
        $value = '['.implode( '', $value ).']';

    $strings[] = $value;
}

return implode( '', $strings );

}

Comments

0

In this code we can't get double quotes in sql query

$sql = array('0'); // Stop errors when $words is empty

foreach($words as $word){
    $sql[] = 'name LIKE %'.$word.'%'
}

$sql = 'SELECT * FROM users WHERE '.implode(" OR ", $sql);

SELECT * FROM person where name like %"Tom"% OR name like %"Smith"% OR name like %"Larry"%;
// error in double quotes and % is out side of Double quotes .

Or you can also use comma separated value:-

$name = array(Tom, Smith, Larry);

$sql="SELECT * FROM person";

    extract($_POST);
    if ($name!=NULL){
    $exp_arr= array_map('trim', explode(",",$name));
    echo var_export($exp_arr);
    //die;
        foreach($exp_arr as $val){
        $arr = "'%{$val}%'";
        $new_arr[] = 'name like '.$arr;
        }

      $new_arr = implode(" OR ", $new_arr);
      echo $sql.=" where ".$new_arr;
    }
        else {$sql.="";}

Echo sql query like this:-

SELECT * FROM person where name like '%Tom%' OR name like '%Smith%' OR name like '%Larry%';

Comments

0

try this: With just one extra line of code :)

$words = array("Tom", "Smith", "Larry"); 

$words = implode("%' OR `name` LIKE '%", $words);
// result -> Tom% OR `name` LIKE %Smith% OR `name` LIKE %Larray

$menus = "SELECT * FROM `users` WHERE `name` LIKE '%" . $words . "%'";
// result -> "... WHERE `name` LIKE %Tom% OR `name` LIKE %Smith% OR `name` LIKE %Larray%";

1 Comment

Please share more details - is this any better than the existing answer?
-2

Many SQL systems let you push it as a character value. CHAR(10) = Linefeed. So, occasionally, instead of working out all the escape coding, you can push single quotes, double quotes and other things into a sql string this way, without too many other coding issues.

-Just a hint.

2 Comments

Hi, welcome to stack overflow. Explain why this is an answer to the question.
Please share more details - how is this even related to the given question?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.