下面的 MySQL 查询使用 PHP 提取 $sector(单个数字)和 $subsector_text(逗号分隔的字符串)。 $subsector_text 可以是单个数字或多个 ID 的列表,例如“3,4,7,9”。
$sql = "
SELECT DISTINCT a.id
, a.name
, a.category_id
, a.sector
, a.subsector
, a.year_in_operation
, a.state
, a.total_value
, b.country_id
, b.project_id
, c.isocode_3
, c.name
FROM com_barchan_project a
JOIN com_barchan_location b
ON b.project_id = a.id
JOIN com_barchan_country c
ON c.id = b.country_id
JOIN com_barchan_project_value_join d
ON a.id = d.project_id
WHERE a.state = 1
AND a.sector = '$sector'
AND a.subsector REGEXP '^{$subsector_text}[,]|[,]{$subsector_text}[,]|[,]{$subsector_text}$|^{$subsector_text}$'
ORDER
BY a.total_value DESC
, a.category_id ASC
, a.name ASC
";
我在上面的查询中遇到的问题是以下行:
AND a.subsector REGEXP '^{$subsector_text}[,]|[,]{$subsector_text}[,]|[,]{$subsector_text}$|^{$subsector_text}$'
如果 $subsector_text = "3,4,5,9",则仅返回 $subsector 字段中恰好包含“3,4,5,9”的记录。
期望的结果是它将返回具有 $subsector_text 中任何值的任何记录。例如,所有这些都应该返回,但目前还没有。此列表只是一个示例,并不准确。
1,3
1,5
1,3,7,9
3,5
3,4,5,9
9
3
5
4
如何更改查询以选择具有 $subsector_text 字符串中的值的任何记录?
请注意:如果 $subsector_text = 11,则不应选择以下内容。
1
12
21
任何帮助将不胜感激。
最佳答案
在单个谓词中将逗号分隔字符串中的任何值与另一个逗号分隔字符串中的任何值进行匹配是不切实际的。
您可以使用FIND_IN_SET()一次搜索一个值。
这意味着您需要多个谓词,一个谓词对应通过拆分输入 $subsector_text
获得的每个值。因此,拆分变量并将其映射到一系列 FIND_IN_SET() 调用中。
我尚未测试以下代码,但它应该能让您了解我在说什么:
$subsector_array = array_map('intval', explode(',', $subsector_text));
$subsector_terms = array_map(
function ($id) { return "FIND_IN_SET($id, a.subsector)"; },
$subsector_array);
$subsector_expr = implode(' OR ', $subsector_terms);
$sql = "
SELECT ...
WHERE a.state = 1
AND a.sector = '$sector'
AND ($subsector_expr)
...";
这当然会强制进行表扫描,因为无法索引 FIND_IN_SET() 或任何其他搜索子字符串的操作。好吧,我想您对 a.state
和 a.sector
的条件将在应用 FIND_IN_SET() 条件之前使用索引来缩小搜索范围。
我理解必须使用您继承的系统所面临的困境。让您的经理知道这需要在某个时候进行重构,因为它永远不会像现在的设计方式那样高效或可靠。
关于php - SQL 查询将逗号分隔的字符串与逗号分隔的字符串进行匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44008546/