2

我在 2020 年 1 月 10 日发布了一个类似的问题(见这里),但我的问题/问题从那时起就扩大了,不想让警察站在我的背上;)

这是标准:

  • 有过滤器类别,并且有属于这些类别的过滤器。
  • 每个过滤器都会显示属于某个过滤器的产品数量。
  • 可用过滤器的数量需要根据活动过滤器的选择减少,不仅是那些仍然适用于产品池的过滤器,还有那些也与其他过滤器类别的子过滤器相关的过滤器。
  • 上面有一个警告,如果只有一个过滤器类别选择了子过滤器,那么所有同级过滤器(相同过滤器类别的过滤器仍将显示)直到另一个过滤器类别的过滤器被激活。一旦选择了来自另一个过滤器类别/父级的过滤器,之前的完整列表可以减少,但之前选择的过滤器必须保持活动状态,如果是这种情况,则只显示零计数。

我认为我非常接近下面的 SQL,但它不会在选择时正确更新属于每个过滤器的产品数量。我可以让它工作的唯一方法是,如果我在下面的 SQL 中将 OR 更改为 AND,但这不会显示属于具有活动子过滤器的过滤器类别的其他子过滤器。

我在这里提供了架构和示例数据,以及相同的http://sqlfiddle.com/#!9/afbd4d7/1/0

CREATE TABLE `store_categories` (
  `categories_id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`categories_id`),
  KEY `idx_categories_parent_id` (`parent_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `store_products` (
  `products_id` int(11) NOT NULL AUTO_INCREMENT,
  `products_status` tinyint(1) NOT NULL,
  PRIMARY KEY (`products_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `store_products_filters` (
  `pf_id` int(11) NOT NULL AUTO_INCREMENT,
  `pf_name` varchar(250) COLLATE utf8_unicode_ci DEFAULT NULL,
  `pf_sort` int(4) DEFAULT '0',
  `pf_to_pfc_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`pf_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `store_products_filters_categories` (
  `pfc_id` int(11) NOT NULL AUTO_INCREMENT,
  `pfc_name` varchar(250) COLLATE utf8_unicode_ci DEFAULT NULL,
  `pfc_sort` int(4) DEFAULT '0',
  PRIMARY KEY (`pfc_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `store_products_filters_to_products` (
  `pftp_id` int(11) NOT NULL AUTO_INCREMENT,
  `pftp_pf_id` int(11) DEFAULT NULL,
  `pftp_products_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`pftp_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `store_products_to_categories` (
  `products_id` int(11) NOT NULL,
  `categories_id` int(11) NOT NULL,
  PRIMARY KEY (`products_id`,`categories_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `store_categories` VALUES ('1', '0');
INSERT INTO `store_categories` VALUES ('2', '1');
INSERT INTO `store_categories` VALUES ('3', '0');
INSERT INTO `store_categories` VALUES ('4', '1');
INSERT INTO `store_categories` VALUES ('5', '0');
INSERT INTO `store_categories` VALUES ('6', '0');
INSERT INTO `store_products` VALUES ('1', '1');
INSERT INTO `store_products` VALUES ('2', '1');
INSERT INTO `store_products` VALUES ('3', '1');
INSERT INTO `store_products` VALUES ('4', '1');
INSERT INTO `store_products` VALUES ('5', '0');
INSERT INTO `store_products_filters` VALUES ('1', 'Small', '0', '1');
INSERT INTO `store_products_filters` VALUES ('2', 'Medium', '0', '1');
INSERT INTO `store_products_filters` VALUES ('3', 'Large', '0', '1');
INSERT INTO `store_products_filters` VALUES ('4', 'Extra Large', '0', '1');
INSERT INTO `store_products_filters` VALUES ('5', 'Circle', '0', '2');
INSERT INTO `store_products_filters` VALUES ('6', 'Square', '0', '2');
INSERT INTO `store_products_filters` VALUES ('7', 'Triangle', '0', '2');
INSERT INTO `store_products_filters` VALUES ('8', 'Red', '5000', '3');
INSERT INTO `store_products_filters` VALUES ('9', 'Blue', '5000', '3');
INSERT INTO `store_products_filters` VALUES ('10', 'Black', '2000', '3');
INSERT INTO `store_products_filters` VALUES ('11', 'Yellow', '5000', '3');
INSERT INTO `store_products_filters_categories` VALUES ('1', 'Size', '300');
INSERT INTO `store_products_filters_categories` VALUES ('2', 'Type', '100');
INSERT INTO `store_products_filters_categories` VALUES ('3', 'Colour', '400');
INSERT INTO `store_products_filters_to_products` VALUES ('1', '1', '1');
INSERT INTO `store_products_filters_to_products` VALUES ('2', '6', '1');
INSERT INTO `store_products_filters_to_products` VALUES ('3', '9', '1');
INSERT INTO `store_products_filters_to_products` VALUES ('4', '1', '2');
INSERT INTO `store_products_filters_to_products` VALUES ('5', '5', '2');
INSERT INTO `store_products_filters_to_products` VALUES ('6', '8', '2');
INSERT INTO `store_products_filters_to_products` VALUES ('7', '2', '3');
INSERT INTO `store_products_filters_to_products` VALUES ('8', '7', '3');
INSERT INTO `store_products_filters_to_products` VALUES ('9', '11', '3');
INSERT INTO `store_products_filters_to_products` VALUES ('10', '3', '4');
INSERT INTO `store_products_filters_to_products` VALUES ('11', '5', '4');
INSERT INTO `store_products_filters_to_products` VALUES ('12', '10', '4');
INSERT INTO `store_products_to_categories` VALUES ('1', '2');
INSERT INTO `store_products_to_categories` VALUES ('2', '2');
INSERT INTO `store_products_to_categories` VALUES ('3', '2');
INSERT INTO `store_products_to_categories` VALUES ('4', '2');
INSERT INTO `store_products_to_categories` VALUES ('5', '2');

有 3 个有源滤波器,Small、Medium 和 Circle。有 2 个“小”尺寸的产品 有 1 个“中”尺寸的产品 有 2 个应用了“圆形”过滤器的产品,但只有一个是“小”,另一个是“大”

应用了中小型过滤器后,我希望/喜欢 Circle 显示 1,但它显示的计数为 2

OR pf.pf_id IN (
        SELECT
            pf_id
        FROM
            store_products_filters
        WHERE
            pf_to_pfc_id IN (1, 2)
    )

到目前为止,我的想法是如果来自多个过滤器类别的过滤器处于活动状态,则删除上述 SQL。

您可以在此站点https://www.ukpos.com/display-stands-frames-and-noticeboards上看到我正在尝试实现的示例,该站点由 Magento 提供支持。我不确定过滤器是开箱即用还是添加了插件。

下面是我的完整 SQL。

SELECT
    pfc.pfc_id,
    pfc.pfc_name,
    pf.pf_id,
    pf.pf_name,
    count(pftp.pftp_pf_id) AS products_in_filter
FROM
    store_products_filters_to_products pftp
LEFT JOIN store_products_filters pf ON pftp.pftp_pf_id = pf.pf_id
LEFT JOIN store_products_filters_categories pfc ON pf.pf_to_pfc_id = pfc_id
WHERE
    pftp_products_id IN (
        SELECT
            ptc.products_id
        FROM
            store_products_to_categories ptc
        LEFT JOIN store_products p ON ptc.products_id = p.products_id
        WHERE
            p.products_status = 1
        AND (
            ptc.categories_id = 1
            OR ptc.categories_id IN (
                SELECT
                    categories_id
                FROM
                    store_categories
                WHERE
                    parent_id = '1'
            )
        )
    )
AND (
    pf.pf_id IN (
        SELECT
            pftp_pf_id
        FROM
            store_products_filters_categories
        WHERE
            pftp_products_id IN (
                SELECT
                    pftp.pftp_products_id
                FROM
                    store_products_filters_to_products pftp
                JOIN store_products_filters pf ON pf.pf_id = pftp.pftp_pf_id
                GROUP BY
                    pftp.pftp_products_id
                HAVING
                    (
                        sum(pf.pf_id = 1) > 0
                        OR sum(pf.pf_id = 2) > 0
                    )
                AND (sum(pf.pf_id = 5) > 0)
            )
    )
    OR pf.pf_id IN (
        SELECT
            pf_id
        FROM
            store_products_filters
        WHERE
            pf_to_pfc_id IN (1, 2)
    )
)
GROUP BY
    pfc.pfc_id,
    pftp.pftp_pf_id
ORDER BY
    pfc.pfc_sort ASC,
    pfc.pfc_name ASC,
    pf.pf_sort ASC,
    pf.pf_name ASC
4

0 回答 0