mysql - 如何将产品计数到按组分隔的多个过滤器中
问题描述
当您从 GROUP X 中选择任何过滤器/选项以将产品计数/更新到其他 GROUPS->过滤器/选项但不在当前组中时,我喜欢为像这样的在线商店这样的产品过滤器制作计数器
例如,如果这是前端过滤器复选框
Size (group_id: 33)
10m (option_id: 52) (21 products)
20m (option_id: 51) (1 product)
Color (group_id: 32)
Green (option_id: 49) (22 products)
Black (option_id: 38) (1 product)
我们只从一个 category_id 127 中寻找结果
同组支票计数示例
如果 option_id: 52 选中
Size (group_id: 33)
[x] 10m (option_id: 52) (21 products)
20m (option_id: 51) (1 product)
Color (group_id: 32)
Green (option_id: 49) (22 products)
Black (option_id: 38) (1 product)
结果:
option_id:38 0,
option_id:49 2,
option_id:51 1,
option_id:52 21
option_id:51 和 52 仍然具有初始状态
如果 option_id: 51 选中
Size (group_id: 33)
10m (option_id: 52) (21 products)
[x] 20m (option_id: 51) (1 product)
Color (group_id: 32)
Green (option_id: 49) (22 products)
Black (option_id: 38) (1 product)
结果:
38 0
49 1
51 1
52 21
option_id:51 和 52 仍然具有初始状态
不同组检查计数的示例
Size (group_id: 33)
[x] 10m (option_id: 52) (21 products)
20m (option_id: 51) (1 product)
Color (group_id: 32)
[x] Green (option_id: 49) (22 products)
Black (option_id: 38) (1 product)
结果:
38 0
49 2
51 1
52 2
所有选项都应更新并失去其初始状态
当您从相同的 group_id 中选择一个或多个 option_id 时,显示产品的逻辑将是
例如:展示尺寸为10m的产品,展示尺寸为20m的产品
如果您首先选择 option_id:51 它不应该更新 option_id:52 因为它们在同一个组中,但会更新 group_id:32 中的所有 option_id 等等
当您从显示产品的不同 group_id 逻辑中选择 option_id 时
例如:显示尺寸为 10m 且颜色为绿色的产品(如果有)
@Akina 完成了本主题中的大部分计数代码
SELECT options.option_id,
COUNT(DISTINCT CASE WHEN filter_counter.option_id = options.option_id
THEN product_id
END) option_count
FROM filter_counter
CROSS JOIN ( SELECT DISTINCT option_id
FROM filter_counter ) options
JOIN ( SELECT DISTINCT product_id
FROM filter_counter
WHERE option_id IN (51) ) filter1 USING (product_id)
GROUP BY options.option_id;
CREATE TABLE `filter_counter` (
`id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
`option_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL,
`manufacturer_id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `filter_counter` (`id`, `group_id`, `option_id`, `product_id`, `category_id`, `manufacturer_id`) VALUES
(1, 33, 52, 5124, 65, 36),
(2, 33, 52, 5124, 127, 36),
(3, 33, 52, 5125, 65, 36),
(4, 33, 52, 5125, 127, 36),
(5, 33, 52, 5138, 65, 36),
(6, 33, 52, 5138, 127, 36),
(7, 33, 52, 5141, 65, 36),
(8, 33, 52, 5141, 127, 36),
(9, 33, 52, 5146, 65, 36),
(10, 33, 52, 5146, 127, 36),
(11, 33, 52, 5147, 65, 36),
(12, 33, 52, 5147, 127, 36),
(13, 33, 52, 5148, 65, 36),
(14, 33, 52, 5148, 127, 36),
(15, 33, 52, 5149, 65, 36),
(16, 33, 52, 5149, 127, 36),
(17, 33, 52, 5150, 65, 36),
(18, 33, 52, 5150, 127, 36),
(19, 33, 52, 5151, 65, 36),
(20, 33, 52, 5151, 127, 36),
(21, 33, 52, 5152, 65, 36),
(22, 33, 52, 5152, 127, 36),
(23, 33, 52, 5153, 65, 36),
(24, 33, 52, 5153, 127, 36),
(25, 33, 52, 5154, 65, 36),
(26, 33, 52, 5154, 127, 36),
(27, 33, 52, 5155, 65, 36),
(28, 33, 52, 5155, 127, 36),
(29, 33, 52, 5156, 65, 36),
(30, 33, 52, 5156, 127, 36),
(31, 33, 52, 5157, 65, 36),
(32, 33, 52, 5157, 127, 36),
(33, 33, 52, 7042, 65, 38),
(34, 33, 52, 7042, 127, 38),
(35, 33, 52, 7048, 65, 38),
(36, 33, 52, 7048, 127, 38),
(37, 33, 52, 7124, 65, 0),
(38, 33, 52, 7124, 127, 0),
(39, 32, 49, 7185, 65, 0),
(40, 32, 49, 7185, 127, 0),
(41, 32, 49, 7517, 65, 39),
(42, 32, 49, 7517, 127, 39),
(43, 32, 49, 7518, 65, 39),
(44, 32, 49, 7518, 127, 39),
(45, 32, 49, 7538, 65, 39),
(46, 32, 49, 7538, 127, 39),
(47, 32, 49, 7657, 65, 39),
(48, 32, 49, 7657, 127, 39),
(49, 32, 49, 7658, 65, 39),
(50, 32, 49, 7658, 127, 39),
(51, 32, 49, 7797, 65, 21),
(52, 32, 49, 7797, 127, 21),
(53, 32, 49, 7798, 65, 21),
(54, 32, 49, 7798, 127, 21),
(55, 32, 49, 7799, 65, 21),
(56, 32, 49, 7799, 127, 21),
(57, 32, 49, 7800, 65, 21),
(58, 32, 49, 7800, 127, 21),
(59, 32, 49, 7801, 65, 21),
(60, 32, 49, 7801, 127, 21),
(61, 32, 49, 7802, 65, 21),
(62, 32, 49, 7802, 127, 21),
(63, 32, 49, 7803, 65, 21),
(64, 32, 49, 7803, 127, 21),
(65, 32, 49, 7804, 65, 21),
(66, 32, 49, 7804, 127, 21),
(67, 32, 49, 7805, 65, 21),
(68, 32, 49, 7805, 127, 21),
(69, 32, 49, 7806, 65, 21),
(70, 32, 49, 7806, 127, 21),
(71, 32, 49, 7807, 65, 21),
(72, 32, 49, 7807, 127, 21),
(73, 32, 49, 7808, 65, 21),
(74, 32, 49, 7808, 127, 21),
(75, 32, 49, 7809, 65, 21),
(76, 32, 49, 7809, 127, 21),
(77, 32, 49, 7810, 65, 21),
(78, 32, 49, 7810, 127, 21),
(79, 32, 38, 7811, 65, 21),
(80, 32, 38, 7811, 127, 21),
(81, 32, 49, 8020, 65, 21),
(82, 32, 49, 8020, 127, 21),
(83, 33, 52, 8020, 65, 21),
(84, 33, 52, 8020, 127, 21),
(85, 32, 49, 8021, 65, 21),
(86, 32, 49, 8021, 127, 21),
(87, 33, 51, 8021, 65, 21),
(88, 33, 51, 8021, 127, 21),
(89, 33, 52, 8021, 65, 21),
(90, 33, 52, 8021, 127, 21);
解决方案
(什么是“问题”?)
我认为实现这一点的最佳方法是基于复选框构建查询,然后在应用程序语言中一次性处理数据。
附带问题:从 MyISAM 切换到 InnoDB。
附带问题:缩小INT
(需要 4 个字节)为更小的数据类型。
这些附带问题背后的重点是性能和空间。许多生成的查询将涉及全表扫描,同时进行过滤。(也就是说,INDEXes
大部分时间都不会有用。)
用户可以单击每个分组中的多个框,对吗?然后考虑让,例如,TINYINT UNSIGNED
它有 8 位(在 1 个字节中)来处理最多8 个选项的所有组合。例如,而不是
AND size_id IN (0, 1) -- 0 means '65in+'; 1 means '50-65in'
做
AND ((size_opts & 0x3) = 0x3)
即 的底部位size_opts
表示 '65in+' 等。
这将大大缩小数据集,并需要不同的预处理来生成查询。
请注意,您的值size_id
是 0..4,我size_opts
的底部 5 位中的部分或全部将打开。
将 (1 << size_id) 值组合在一起可以让您从size_id
到size_opts
.
(更多的)
有两件事发生:
- 过滤(按品牌/价格/颜色/其他限制显示)
- 计算有多少仍在运行中(按每个剩余标准)
需要达到目标才能使其有点效率:
- 尽可能缩小数据集
- 不要在表中包含任何“已删除”的项目等。不要包含任何与过滤和计数无关的列。他们与收缩目标作斗争
- 尽可能缩小分类。我建议的“摆弄”可能是最佳选择。
- 动态构建查询。省去不必要的测试。(例如:品牌没有点击时,不要测试品牌。)
- 换句话说,就是为此目的建立一个表。专注于它;忽略数据的所有其他方面。即使这张表中的数据是多余的,你也必须优化这张表。
推荐阅读
- c# - 如何为谷歌日历集成创建 credentials.json
- javascript - 在表格中书写时如何替换字符?
- numpy - 高效计算 Numpy 中所有其他元素的乘积
- json - 如何在模板中以角度绑定模型对象中的单个元素
- perl - 在 Perl 严格模式下从变量访问完全限定的变量名
- ios - 从 Podfile 等更改 XCode Target > Build Settings > Architecture
- javascript - 如何在 Svelte 中的不同事件上触发相同的功能
- github - 使用新服务器创建新的 SSH 密钥,还是使用现有密钥?
- python - 如何使用 tf.keras.preprocessing.image.ImageDataGenerator ( TENSORFLOW 2.0 ) 更改某些样本的标签
- c# - WinAppDriver:是否可以通过 AccessibilityId(自动化 ID)的实例创建