如何在SQL查询的IN子句中匹配表行的逗号分隔值?
问题:如何匹配包含指定size_id值的记录?
你现在有一组用PHP数组模拟的model表数据:
$model = array( array('id' => '1','category_id' => '1','size_id' => '1,2,3','series_id' => '1','model_no' => 'AI-5441','display_height' => '','Weight' => '','image' => '20382mode1.jpg'), array('id' => '2','category_id' => '1','size_id' => '3','series_id' => '1','model_no' => 'AI-5741','display_height' => '','Weight' => '','image' => '19391mode1.jpg'), array('id' => '3','category_id' => '1','size_id' => '4','series_id' => '1','model_no' => 'AI-5841','display_height' => '','Weight' => '','image' => '8242mode1.jpg') );
当前你用的SQL语句是:
$sql = "SELECT * from model Where size_id IN ('1')";
但这个语句只能匹配size_id完全等于'1'的记录,没法覆盖像id=1那种size_id是'1,2,3'的行。下面给你几种实用的解决思路:
方法1:用MySQL的FIND_IN_SET函数(最直接的数据库方案)
MySQL自带的FIND_IN_SET函数专门用来在逗号分隔的字符串里查找指定值,完美适配你的场景:
$sql = "SELECT * FROM model WHERE FIND_IN_SET('1', size_id) > 0";
这个函数会返回目标值在字符串中的位置,找到的话就会返回大于0的数字,这样就能精准匹配所有包含1的size_id记录。
方法2:PHP端拼接模糊查询条件(适合动态多值场景)
如果你的查询条件是动态生成的,也可以在PHP里拼接LIKE条件来覆盖所有可能的匹配情况:
$targetSize = '1'; $sql = "SELECT * FROM model WHERE size_id = '$targetSize' OR size_id LIKE '$targetSize,%' OR size_id LIKE '%,$targetSize' OR size_id LIKE '%,$targetSize,%'";
⚠️ 注意:直接拼接字符串有SQL注入风险,推荐用预处理语句更安全:
$targetSize = '1'; $stmt = $pdo->prepare("SELECT * FROM model WHERE size_id = ? OR size_id LIKE ? OR size_id LIKE ? OR size_id LIKE ?"); $stmt->execute([$targetSize, "$targetSize,%", "%,$targetSize", "%,$targetSize,%"]); $results = $stmt->fetchAll();
方法3:优化数据库结构(长期推荐方案)
把size_id存成逗号分隔的字符串其实不符合数据库设计的范式,后续维护和查询都会有隐患。更规范的做法是新建一个关联表model_size,结构如下:
| model_id | size_id |
|---|---|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 3 |
| 3 | 4 |
然后用关联查询获取数据:
$sql = "SELECT m.* FROM model m JOIN model_size ms ON m.id = ms.model_id WHERE ms.size_id = '1'";
这种方式查询效率更高,也能避免字符串匹配的各种边缘问题,方便后续功能扩展。
内容的提问来源于stack exchange,提问作者Amarjeet
相关产品推荐
相关产品推荐

