我正在为基于 EAV(实体-模型-价值在本主题中称为产品-选项-价值)模型的在线商店构建多面过滤器。使用以下逻辑过滤产品:
... pv.value_id IN (option_value1 or option_value1) AND pv.value_id IN (option_value2 or option_value2)
在这样实现的查询中(没有 FIND_IN_SET 但提供许多查询):
$pids=数组();
foreach ($option as $values) {
$sqli = "SELECT product_id FROM product_to_value WHERE value_id in ('" . implode(",", $values) . "') ";
$query =$db->query($sqli);foreach ($query->rows as $row){ $pids[] = $row['product_id']; } }
$sql .= " AND p.product_id IN (" . implode(",", $pids) . ")";
另一个任务是考虑依赖关系的选项值计算产品的解决方案(例如,下面的查询选择给定现有过滤的所有可能产品,10 - 是 option1 的值,6,8 - 是 option2 的值)
SELECT p.product_id, pv.value_id, GROUP_CONCAT(pv.value_id) as value_ids FROM
product
p INNER JOIN product_to_value pv ON (p.product_id = pv.product_id) WHERE pv.value_id<>0 GROUP BY product_id HAVING (FIND_IN_SET(10, value_ids ) >0 ) AND ( FIND_IN_SET( 6, value_ids ) >0 或 FIND_IN_SET( 8, value_ids ) >0 )
之后,获取选定产品的值计数。
问题:这看起来不是完美的解决方案,任何想法如何改进此代码以计算/过滤考虑过滤选项的产品。使用或记下 FIND_IN_SET
和 SQL 模式以便更好地理解:
CREATE TABLE `option` (
`option_id` int(10) NOT NULL auto_increment,
`status` int(1) default '0',
`sort_order` int(10) default '0',
PRIMARY KEY (`option_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `option_value` (
`value_id` int(10) NOT NULL auto_increment,
`name` varchar(127) NOT NULL,
`option_id` int(10) default '0',
PRIMARY KEY (`value_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `product_to_value` (
`product_id` int(11) NOT NULL,
`value_id` int(11) NOT NULL,
`option_id` int(11) NOT NULL,
PRIMARY KEY (`product_id`,`value_id`,`option_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `product` (
`product_id` int(11) NOT NULL auto_increment,
PRIMARY KEY (`product_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
更新:
没有 FIND_IN_SET 的附加变体。
SELECT product_id FROM product_to_value WHERE product_id IN (SELECT product_id FROM product_to_value WHERE value_id IN (6,8) GROUP BY product_id) AND product_id IN (SELECT product_id FROM product_to_value WHERE value_id IN (10) GROUP BY product_id) GROUP BY product_id
哪个变体更好或不同的解决方案?