我正在为基于EAV(ENTITY - MODEL -VALUE,名为PRODUCT - OPTION -VALUE)的模型构建在线商店的分面过滤器。 使用以下逻辑过滤产品:
... pv.value_id IN (option_value1 or option_value1) AND pv.value_id IN (option_value2 or option_value2)
在这样实现的查询中(没有FIND_IN_SET但提供了许多查询):
$的PID =阵列();
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
哪种变体是更好还是不同的解决方案?