You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用MySQL查询含多数组单元格的8万行数据表?

解决MySQL逗号分隔字段的搜索问题

首先咱们先理清楚核心问题:你需要从prod_designs表中查询那些pd_year字段(逗号分隔的年份字符串)包含搜索条件中任意一个年份的记录,而搜索条件来自prod_desigs_search_test表的pds_year字段(同样是逗号分隔的字符串,可能为空)。

现有代码的关键问题

你之前的代码里有个致命错误:从数据库取出的$pd_year_ex是字符串类型,不是数组,所以is_array($pd_year_ex)这个判断永远不会成立,导致你只能处理单个年份的情况,完全无法匹配多个年份的场景。

另外,直接用LIKE '%年份字符串%'的方式不够准确——比如如果搜索条件是201,会误匹配到2017;而且如果目标表的pd_year是2017,2018,搜索条件是2017,2016,LIKE '%2017,2016%'也匹配不到,因为目标字段里没有这个完整的子串。

正确的实现方案

MySQL提供了专门处理逗号分隔字符串的函数FIND_IN_SET(str, strlist),它会返回str在strlist(逗号分隔的字符串)中的位置,不存在则返回0。用这个函数可以准确匹配单个年份是否存在于目标字段中。

1. 处理搜索条件

先从prod_desigs_search_test取出搜索条件,处理空值并分割成年份数组:

$get_search = mysqli_query($con, "SELECT * FROM prod_desigs_search_test WHERE s_id = '$s_id'");
$new_search = mysqli_fetch_array($get_search);
$pd_year_ex = trim($new_search['pds_year']); // 去掉空格,处理你插入时的' '情况

$year_conditions = [];
if (!empty($pd_year_ex)) {
    $years = explode(",", $pd_year_ex);
    // 遍历每个年份,生成FIND_IN_SET条件
    foreach ($years as $year) {
        $year = trim($year); // 去掉年份前后可能的空格
        if (!empty($year)) { // 过滤空的年份(比如字符串里有连续逗号的情况)
            $year_conditions[] = "FIND_IN_SET('$year', pd_year)";
        }
    }
}

2. 构建WHERE子句并执行查询

根据生成的条件数组,拼接成最终的查询语句:

$where_clause = "";
if (!empty($year_conditions)) {
    $where_clause = "WHERE " . implode(" OR ", $year_conditions);
}

// 执行查询
$search_sql = "SELECT * FROM prod_designs $where_clause";
$search = mysqli_query($con, $search_sql);

如果搜索条件是2017,2016,2015,最终生成的SQL会是:

SELECT * FROM prod_designs WHERE FIND_IN_SET('2017', pd_year) OR FIND_IN_SET('2016', pd_year) OR FIND_IN_SET('2015', pd_year)

这个查询会准确找出所有pd_year字段包含这三个年份中任意一个的记录。

3. 针对8万行数据的优化建议

  • 解决SQL注入风险:你现在直接把变量拼进SQL的做法非常危险,建议改用预处理语句:
    if (!empty($year_conditions)) {
        // 生成占位符字符串
        $placeholder_str = implode(', ', array_fill(0, count($years), '?'));
        // 生成条件模板
        $condition_template = implode(' OR ', array_fill(0, count($years), 'FIND_IN_SET(?, pd_year)'));
        $search_sql = "SELECT * FROM prod_designs WHERE $condition_template";
        
        $stmt = mysqli_prepare($con, $search_sql);
        // 绑定参数,str_repeat('s', count($years))表示所有参数都是字符串类型
        mysqli_stmt_bind_param($stmt, str_repeat('s', count($years)), ...$years);
        mysqli_stmt_execute($stmt);
        $search = mysqli_stmt_get_result($stmt);
    }
    
  • 提升查询性能:FIND_IN_SET无法使用索引,8万行数据的话查询可能会变慢。如果长期有这类需求,建议重构表结构——把逗号分隔的年份拆分成单独的关联表(比如design_years,包含design_id和year字段),这样可以用索引快速查询,性能会提升很多。

空字段处理

如果pd_year_ex为空,$where_clause会是空字符串,查询会返回prod_designs表的所有记录;如果目标表的pd_year字段为空,FIND_IN_SET会返回0,不会被匹配到。如果你想匹配空字段,可以在条件里加上OR pd_year IS NULL OR pd_year = ''。

内容的提问来源于stack exchange,提问作者Andrew Ferguson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:47:58