根据当前选择添加额外的商店过滤器

tct7dpnv  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(288)

我有下表(mysql数据库,表产品\u属性):
产品标识属性标识属性值标识
我有当前产品ID(按类别或搜索查询过滤),可以用来过滤表;这将确保我将建立基于当前过滤产品的所有可用过滤器。
我的问题是,我必须建立过滤器列表的基础上,目前的产品,并能够添加一些额外的,将允许我扩大结果;这些过滤器将来自至少有n-1个应用过滤器的产品;n过滤器将是额外的一个。
例子:
我对鞋类和过滤的颜色(黑色)和大小(40);在我的过滤器列表中,我现在得到了颜色:黑色和大小:40(过滤);在这种情况下,我也有产品的颜色黑色,但大小是42;我需要42显示在大小过滤器作为一个可行的选择,因为这方面的n-1规则额外的过滤器。
我不知道如何在一个sql查询中做到这一点。其思想是在表中查找至少有n-1个选定过滤器作为属性值id的产品id;结果应该是包含当前筛选器和额外可行筛选器的属性值ID的唯一集合。
也许这更有用:
这是我的筛选条件(属性\ id,属性\值\ id):(1,12)和(6268)。
这意味着过滤器列表将由所有过滤产品组成,但没有额外的可行选项。如果我运行这个,那么在本例中,我将拥有属于当前类别的所有产品:
查询:

select * from product_attributes 
where product_id in (812,813,814,815,816,817,818,819,820,1361,1362,1465,1466,1582,1583,1784,1794,1795,1802);

结果


# product_id, attribute_id, attribute_value_id

'812', '1', '12'
'812', '2', '13'
'812', '6', '139'
'813', '1', '12'
'813', '2', '13'
'813', '6', '249'
'814', '1', '12'
'814', '2', '13'
'814', '6', '268'
'815', '1', '12'
'815', '2', '13'
'815', '6', '249'
'816', '1', '12'
'816', '2', '13'
'816', '6', '249'
'817', '1', '12'
'817', '2', '13'
'817', '6', '268'
'818', '1', '12'
'818', '2', '13'
'818', '6', '249'
'819', '1', '12'
'819', '2', '277'
'819', '6', '310'
'820', '1', '12'
'820', '2', '13'
'820', '6', '93'
'1361', '1', '12'
'1361', '2', '36'
'1362', '1', '12'
'1465', '1', '12'
'1465', '2', '13'
'1465', '6', '249'
'1466', '1', '12'
'1466', '2', '13'
'1466', '6', '268'
'1582', '1', '12'
'1582', '2', '277'
'1582', '6', '139'
'1583', '1', '12'
'1583', '2', '277'
'1583', '6', '516'
'1784', '1', '12'
'1784', '2', '13'
'1784', '6', '139'
'1794', '1', '12'
'1794', '2', '13'
'1794', '6', '93'
'1802', '1', '12'
'1802', '2', '66'
'1802', '6', '93'

如果我应用过滤器(1,12)和(6268),那么只剩下这个产品:814,817,1466
我想要得到的结果是:
id为812的产品具有(1,12)、(2,13)、(6,139)的组合;因为我正在应用(1,12)和(6268)的过滤组合,所以这个产品有n-1个过滤器组合,所以139应该作为一个新的可行选项添加到过滤器列表中。
这是我用来生成sql的代码:

$wheres = [];

        foreach ($this->appliedFilters as $attributeId => $attributeValuesIds) {
            foreach ($attributeValuesIds as $attributeValueId) {
                $wheres[] = "attribute_id = {$attributeId} and attribute_value_id = {$attributeValueId}";
            }
        }

        $filteredSql = "SELECT * FROM product_attributes WHERE product_id IN (".implode(',', $this->filteredProductsIds).")";

        $filtersSql = 'SELECT * FROM product_attributes WHERE product_id IN (SELECT DISTINCT product_id FROM product_attributes';

        $firstWhere = array_shift($wheres);

        $filtersSql .= " WHERE ({$firstWhere})";

        foreach ($wheres as $where) {
            $filtersSql .= " OR ({$where})";
        }

        $filtersSql .= ')';

        $mergedSql = "
            SELECT A.attribute_value_id, A.attribute_id FROM ({$filteredSql}) as A
            INNER JOIN ({$filtersSql}) AS B ON B.product_id = A.product_id";
echo "$filteredSql $filtersSql $mergedSql";

输出的sql为:

SELECT * FROM product_attributes WHERE product_id IN (812,813,814,815,816,817,818,819,820,1361,1362,1465,1466,1582,1583,1784,1794,1795,1802)
SELECT * FROM product_attributes WHERE product_id IN (SELECT DISTINCT product_id FROM product_attributes WHERE (attribute_id = 1 and attribute_value_id = 12) OR (attribute_id = 2 and attribute_value_id = 277))
SELECT A.attribute_value_id, A.attribute_id FROM (SELECT * FROM product_attributes WHERE product_id IN (812,813,814,815,816,817,818,819,820,1361,1362,1465,1466,1582,1583,1784,1794,1795,1802)) as A INNER JOIN (SELECT * FROM product_attributes WHERE product_id IN (SELECT DISTINCT product_id FROM product_attributes WHERE (attribute_id = 1 and attribute_value_id = 12) OR (attribute_id = 2 and attribute_value_id = 277))) AS B ON B.product_id = A.product_id

最终sql的结果是:

'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'12', '1'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'13', '2'
'36', '2'
'36', '2'
'66', '2'
'66', '2'
'66', '2'
'93', '6'
'93', '6'
'93', '6'
'93', '6'
'93', '6'
'93', '6'
'93', '6'
'93', '6'
'93', '6'
'139', '6'
'139', '6'
'139', '6'
'139', '6'
'139', '6'
'139', '6'
'139', '6'
'139', '6'
'139', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'249', '6'
'268', '6'
'268', '6'
'268', '6'
'268', '6'
'268', '6'
'268', '6'
'268', '6'
'268', '6'
'268', '6'
'277', '2'
'277', '2'
'277', '2'
'277', '2'
'277', '2'
'277', '2'
'277', '2'
'277', '2'
'277', '2'
'310', '6'
'310', '6'
'310', '6'
'516', '6'
'516', '6'
'516', '6'

像23/249这样的值对于返回的产品是无效的。我得到了我需要的额外价值,但我也得到了。

rt4zxlrg

rt4zxlrg1#

在示例查询中需要做的就是用子查询替换产品id的列表。

SELECT *
FROM   product_attributes
WHERE  product_id IN
                      (
                      SELECT DISTINCT product_id
                      FROM            product_attributes
                      WHERE           (
                                                      attribute_id='a'
                                      AND             attribute_value_id='x')
                      OR             (
                                                      attribute_id='b'
                                      AND             attribute_value_id='y') ;

相关问题