在 FIND_IN_SET 中找到多根针
Find multiple needles in FIND_IN_SET
我有一个可能包含逗号分隔列表的变量。在我的数据库中,我还有一列带有列分隔列表。
我知道我可以使用 FIND_IN_SET(needle, haystack)
在该数据库列中找到单个值
但是,如果我的变量包含一个列表,例如 "a,b,c",我如何检查列表中的至少一项是否与列中的至少一项相匹配?这可能吗?
听起来您的数据库中可能需要一些链接表。在列中存储逗号分隔列表以与其他逗号分隔列表进行比较,如果您达到任何规模,都会损害您的性能。
我强烈建议您阅读更多有关链接表(关联实体)的内容,以说服您稍微更改数据库设计:
https://en.wikipedia.org/wiki/Associative_entity
要回答有关如何使用 FIND_IN_SET
在单个查询中执行多个搜索的问题,您需要动态构建查询。
这里有一个基本示例,可以简单地向您展示如何动态构建查询。 请采取适当的措施防止SQL注入(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 . ';';
这会产生以下查询:
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
示例查询将生成 1
,表明您的搜索值之一在您的集合中。
SELECT `column_A` REGEXP CONCAT('(,|^)(', REPLACE( `column_B` ,',','|'), ')(,|$)');
SELECT '123,456,789' REGEXP CONCAT('(,|^)(', REPLACE( '1234,456,6789' ,',','|'), ')(,|$)');
这是我的解决方案。
我有一个可能包含逗号分隔列表的变量。在我的数据库中,我还有一列带有列分隔列表。
我知道我可以使用 FIND_IN_SET(needle, haystack)
但是,如果我的变量包含一个列表,例如 "a,b,c",我如何检查列表中的至少一项是否与列中的至少一项相匹配?这可能吗?
听起来您的数据库中可能需要一些链接表。在列中存储逗号分隔列表以与其他逗号分隔列表进行比较,如果您达到任何规模,都会损害您的性能。
我强烈建议您阅读更多有关链接表(关联实体)的内容,以说服您稍微更改数据库设计: https://en.wikipedia.org/wiki/Associative_entity
要回答有关如何使用 FIND_IN_SET
在单个查询中执行多个搜索的问题,您需要动态构建查询。
这里有一个基本示例,可以简单地向您展示如何动态构建查询。 请采取适当的措施防止SQL注入(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 . ';';
这会产生以下查询:
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
示例查询将生成 1
,表明您的搜索值之一在您的集合中。
SELECT `column_A` REGEXP CONCAT('(,|^)(', REPLACE( `column_B` ,',','|'), ')(,|$)');
SELECT '123,456,789' REGEXP CONCAT('(,|^)(', REPLACE( '1234,456,6789' ,',','|'), ')(,|$)');
这是我的解决方案。