如何在Yii 1.1中获取product_category_id含指定ID的产品表数据?
在Yii 1.1中查询包含特定分类ID的产品记录
我来帮你解决这个问题——在Yii 1.1里处理这种逗号分隔的分类ID查询有几种靠谱的方法,不过先得提一句:这种把多个ID存在单个字符串字段里的设计其实不太符合数据库规范,数据量大的时候查询性能会受影响(因为没法用到索引),最好的长远方案是改成多对多关联表(比如新建product_category表,存product_id和category_id的关联关系)。不过如果你现在需要先解决当前的查询需求,下面是几种可行的方案:
方法1:使用MySQL的FIND_IN_SET函数(推荐)
MySQL的FIND_IN_SET()函数专门用来处理逗号分隔的字符串列表,它会返回指定值在列表中的位置(如果存在的话),非常适合你的场景。
Yii 1.1代码示例(用CDbCriteria)
// 要查询的目标分类ID $targetCategoryId = 3; // 构建查询条件 $criteria = new CDbCriteria(); // 使用FIND_IN_SET判断目标ID是否在product_category_id的列表中 $criteria->addCondition('FIND_IN_SET(:categoryId, product_category_id)'); // 绑定参数,防止SQL注入 $criteria->params[':categoryId'] = $targetCategoryId; // 查询符合条件的所有产品 $products = Product::model()->findAll($criteria);
注意事项
- 如果你的
product_category_id字段里有空格(比如"1, 3, 4"),FIND_IN_SET会匹配失败,这时候需要先去掉空格:$criteria->addCondition('FIND_IN_SET(:categoryId, REPLACE(product_category_id, " ", ""))'); - 这个方法比LIKE更可靠,不需要手动处理字符串边界(比如避免把
1误匹配成11)。
方法2:使用LIKE匹配(需处理边界)
如果你不想用FIND_IN_SET,也可以通过拼接字符串边界的方式用LIKE查询,核心是确保目标ID被逗号包裹,避免误匹配。
Yii 1.1代码示例
$targetCategoryId = 3; $criteria = new CDbCriteria(); // 拼接成",product_category_id,"的形式,然后匹配",3," $criteria->addCondition("CONCAT(',', product_category_id, ',') LIKE :pattern"); $criteria->params[':pattern'] = "%," . $targetCategoryId . ",%"; $products = Product::model()->findAll($criteria);
注意事项
- 同样,如果字段里有空格,需要先替换掉:
$criteria->addCondition("CONCAT(',', REPLACE(product_category_id, ' ', ''), ',') LIKE :pattern"); - 这种方法同样无法使用索引,数据量大时性能会很差。
关于性能和数据库设计的建议
虽然上面的方法能解决当前问题,但我还是强烈建议你重构数据库结构:
- 新建一张
product_category关联表,字段包括product_id(外键关联products.product_id)和category_id(外键关联分类表的主键)。 - 把原来
products.product_category_id里的多ID拆分到关联表中,比如原记录product_id=1, product_category_id="1,3,4"就拆成三条关联记录:(1,1)、(1,3)、(1,4)。
这样查询的时候,你可以用Yii的关联查询,不仅性能更好(能用到索引),还能轻松实现更复杂的查询(比如同时属于多个分类的产品):
// 关联查询示例(假设已经在Product模型里定义了relations) $products = Product::model()->with('categories')->findAll('categories.category_id = :id', array(':id' => 3));
内容的提问来源于stack exchange,提问作者Dev789
相关产品推荐
相关产品推荐

