简体   繁体   中英

Find multiple needles in FIND_IN_SET

I have a variable that may contain a comma separated list. In my database, I also have a column with a column separated list.

I know I can find a single value in that db column by using FIND_IN_SET(needle, haystack)

However, if my variable contains a list such as "a,b,c" how can I check if at least one item in the list matches at least one item in the column? Is this possible?

It sounds like you probably need some linking tables in your database. Storing comma separated lists in columns to compare against other comma separated lists is going to hurt your performance if you get to any sort of scale.

I'd highly suggest you read more about linking tables (associative entities) to perhaps convince you to change your database design somewhat: https://en.wikipedia.org/wiki/Associative_entity

To answer your question about how you would use FIND_IN_SET to perform multiple searches in a single query, you would need to build your query dynamically.

Here is a basic example to simply show you how to build a query dynamically. Please take proper steps to prevent SQL injection ( http://php.net/manual/en/security.database.sql-injection.php ).

// This is the list you want to search against - for your actual implementation you would use your column name
$haystack_str = '2,4,6,8,10';

// This is the comma separated list you want to use as your needle
$search_str = '1,2,3';

// Break the string apart into separate values
$search_array = explode(',', $search_str);

// Store your query fragments
$query_array = array();

// Loop through each string value you want to use as your needle
foreach ($search_array as $needle) {
    // PLEASE TAKE PRECAUTIONS AGAINST SQL INJECTION !!!
    $query_array[] = sprintf('FIND_IN_SET("%s","%s")', $needle, $haystack_str);
}

// Join all pieces together using OR
$query_str = implode(' OR ', $query_array);

// Show your example query
echo 'SELECT ' . $query_str . ';';

Example: https://eval.in/867963

This produces the following query: SELECT FIND_IN_SET("1","2,4,6,8,10") OR FIND_IN_SET("2","2,4,6,8,10") OR FIND_IN_SET("3","2,4,6,8,10");

Returns a value in the range of 1 to N if the string str is in the string list strlist consisting of N substrings. Returns 0 if str is not in strlist or if strlist is the empty string. https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_find-in-set

The sample query will produce 1 which indicates one of your search values is in your set.

SELECT `column_A` REGEXP CONCAT('(,|^)(', REPLACE( `column_B` ,',','|'), ')(,|$)');

SELECT '123,456,789' REGEXP CONCAT('(,|^)(', REPLACE( '1234,456,6789' ,',','|'), ')(,|$)');

This is my solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM