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

MySQL单表查询相似兴趣用户的最优匹配方案求助

解决方案

首先你需要提前在PHP中取出目标用户的userInterests字段值,拆分为兴趣ID数组,比如目标用户为userA时,对应的兴趣ID数组为[1,2,10],总兴趣数为3。

单表SQL查询方案

不需要JOIN操作,通过FIND_IN_SET函数统计兴趣重合数即可实现需求,SQL写法参考如下:

SELECT 
    userName,
    userEmail,
    userInterests,
    -- 统计与目标用户的兴趣重合数量
    (
        (FIND_IN_SET('1', userInterests) > 0) +
        (FIND_IN_SET('2', userInterests) > 0) +
        (FIND_IN_SET('10', userInterests) > 0)
    ) AS match_count
FROM 
    你的表名
WHERE 
    -- 排除目标用户自身
    userName != 'userA'
    -- 可选过滤:仅保留至少有1个兴趣重合的用户
    AND match_count > 0
ORDER BY 
    -- 完全匹配优先:重合数等于目标用户总兴趣数的结果排最前
    (match_count = 3) DESC,
    -- 其余按重合数量降序排序
    match_count DESC;

PHP动态生成SQL示例

由于不同目标用户的兴趣数量不固定,你可以在PHP中动态拼接判断逻辑,适配所有目标用户的查询需求:

// 已从数据库取出的目标用户信息
$target_username = 'userA';
$target_interests_str = '1,2,10';
$target_interest_arr = explode(',', $target_interests_str);
$target_total_count = count($target_interest_arr);

// 动态拼接重合数计算逻辑
$match_rules = [];
foreach ($target_interest_arr as $interest_id) {
    $interest_id = addslashes($interest_id);
    $match_rules[] = "(FIND_IN_SET('{$interest_id}', userInterests) > 0)";
}
$match_count_sql = implode(' + ', $match_rules);
$target_username = addslashes($target_username);

// 最终执行的SQL
$final_sql = "
SELECT 
    userName,
    userEmail,
    userInterests,
    ({$match_count_sql}) AS match_count
FROM 
    你的表名
WHERE 
    userName != '{$target_username}'
    AND match_count > 0
ORDER BY 
    (match_count = {$target_total_count}) DESC,
    match_count DESC
";

补充说明

  • 性能优化:如果表数据量超过10万,建议对userInterests字段增加全文索引,或者调整表结构将兴趣拆分到独立的关联表,查询性能会有明显提升
  • 安全提示:拼接SQL时务必做好参数转义,避免SQL注入风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 01:39:03