如何使用 MySQL 应用产品范围过滤器
How can I apply product range filters using MySQL
我正在努力为我的一个项目解决这个问题。我正在使用 codeigniter 3 和 MySQL 8。所以请专家帮助我。这是描述。
我有如下 2 个表:
产品:
| id | name |
| -- | --------- |
| 1 | Product 1 |
| 2 | Product 2 |
| 3 | Product 3 |
| 4 | Product 4 |
产品过滤器:
| product_id | filter_id | value |
| ---------- | --------- | ------ |
| 1 | 1 | 60 |
| 1 | 2 | 40 |
| 2 | 1 | 400 |
| 2 | 2 | 30 |
| 3 | 1 | 80 |
| 3 | 2 | 20 |
| 4 | 1 | 50 |
| 4 | 2 | 100 |
SQL供您参考:
CREATE TABLE IF NOT EXISTS `product` (
`id` int(10) unsigned NOT NULL,
`name` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `product` (`id`, `name`) VALUES
('1', 'Product 1'),
('2', 'Product 2'),
('3', 'Product 3'),
('4', 'Product 4');
CREATE TABLE IF NOT EXISTS `product_filter` (
`product_id` int(10) unsigned NOT NULL,
`filter_id` int(10) unsigned NOT NULL,
`value` int(10) unsigned NOT NULL
) DEFAULT CHARSET=utf8;
INSERT INTO `product_filter` (`product_id`, `filter_id`, `value`) VALUES
('1', '1', '60'),
('1', '2', '40'),
('2', '1', '400'),
('2', '2', '30'),
('3', '1', '80'),
('3', '2', '20'),
('4', '1', '50'),
('4', '2', '100');
http://sqlfiddle.com/#!9/8c071f
对于一个产品,可以有多个过滤器,如上。但不能两次使用相同的过滤器。对于每个产品,每个过滤器都可以有一个值。
我想要以下场景:
- 过滤器 1 和介于 0 到 200 之间的值和
- 过滤器 2 和介于 0 到 50 之间的值。
例如,我有 10 个电源适配器。我想用电压和瓦特过滤掉它。因此,过滤器 1 将是电压,而 2 将是瓦特。现在我发送范围值以通过 0 - 200 伏和 0 - 50 瓦的消耗过滤特定产品。我的意思是这两个条件都应该适用。
结果应该是产品列表:
| id | name |
| -- | --------- |
| 1 | Product 1 |
| 3 | Product 3 |
我使用多个 AND 尝试了以下 sql,它的 return 是一个空结果。这是我使用的示例查询。
SELECT p.*
FROM product p
JOIN product_filter fp ON fp.product_id = p.id
WHERE
(
fp.filter_id = 1 AND fp.value >= 0 AND fp.value <= 200
) AND
(
fp.filter_id = 2 AND fp.value >= 0 AND fp.value <= 50
)
我怎样才能得到上面的答案?请帮忙。
考虑以下因素:
SELECT product_id
, MAX(CASE WHEN filter_id = 1 THEN value END) v
, MAX(CASE WHEN filter_id = 2 THEN value END) w
FROM product_filter
GROUP
BY product_id;
+------------+------+------+
| product_id | v | w |
+------------+------+------+
| 1 | 60 | 40 |
| 2 | 400 | 30 |
| 3 | 80 | 20 |
| 4 | 50 | 100 |
+------------+------+------+
因此,为了我们的目的,这可以重新排列为...
SELECT product_id
FROM product_filter
GROUP
BY product_id
HAVING MAX(CASE WHEN filter_id = 1 THEN value END) BETWEEN 0 AND 200
AND MAX(CASE WHEN filter_id = 2 THEN value END) BETWEEN 0 AND 50
;
+------------+
| product_id |
+------------+
| 1 |
| 3 |
+------------+
请注意,这不太可能比您多次加入 table 的想法更有效,但它更易于阅读。
我正在努力为我的一个项目解决这个问题。我正在使用 codeigniter 3 和 MySQL 8。所以请专家帮助我。这是描述。
我有如下 2 个表:
产品:
| id | name |
| -- | --------- |
| 1 | Product 1 |
| 2 | Product 2 |
| 3 | Product 3 |
| 4 | Product 4 |
产品过滤器:
| product_id | filter_id | value |
| ---------- | --------- | ------ |
| 1 | 1 | 60 |
| 1 | 2 | 40 |
| 2 | 1 | 400 |
| 2 | 2 | 30 |
| 3 | 1 | 80 |
| 3 | 2 | 20 |
| 4 | 1 | 50 |
| 4 | 2 | 100 |
SQL供您参考:
CREATE TABLE IF NOT EXISTS `product` (
`id` int(10) unsigned NOT NULL,
`name` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `product` (`id`, `name`) VALUES
('1', 'Product 1'),
('2', 'Product 2'),
('3', 'Product 3'),
('4', 'Product 4');
CREATE TABLE IF NOT EXISTS `product_filter` (
`product_id` int(10) unsigned NOT NULL,
`filter_id` int(10) unsigned NOT NULL,
`value` int(10) unsigned NOT NULL
) DEFAULT CHARSET=utf8;
INSERT INTO `product_filter` (`product_id`, `filter_id`, `value`) VALUES
('1', '1', '60'),
('1', '2', '40'),
('2', '1', '400'),
('2', '2', '30'),
('3', '1', '80'),
('3', '2', '20'),
('4', '1', '50'),
('4', '2', '100');
http://sqlfiddle.com/#!9/8c071f
对于一个产品,可以有多个过滤器,如上。但不能两次使用相同的过滤器。对于每个产品,每个过滤器都可以有一个值。
我想要以下场景:
- 过滤器 1 和介于 0 到 200 之间的值和
- 过滤器 2 和介于 0 到 50 之间的值。
例如,我有 10 个电源适配器。我想用电压和瓦特过滤掉它。因此,过滤器 1 将是电压,而 2 将是瓦特。现在我发送范围值以通过 0 - 200 伏和 0 - 50 瓦的消耗过滤特定产品。我的意思是这两个条件都应该适用。
结果应该是产品列表:
| id | name |
| -- | --------- |
| 1 | Product 1 |
| 3 | Product 3 |
我使用多个 AND 尝试了以下 sql,它的 return 是一个空结果。这是我使用的示例查询。
SELECT p.*
FROM product p
JOIN product_filter fp ON fp.product_id = p.id
WHERE
(
fp.filter_id = 1 AND fp.value >= 0 AND fp.value <= 200
) AND
(
fp.filter_id = 2 AND fp.value >= 0 AND fp.value <= 50
)
我怎样才能得到上面的答案?请帮忙。
考虑以下因素:
SELECT product_id
, MAX(CASE WHEN filter_id = 1 THEN value END) v
, MAX(CASE WHEN filter_id = 2 THEN value END) w
FROM product_filter
GROUP
BY product_id;
+------------+------+------+
| product_id | v | w |
+------------+------+------+
| 1 | 60 | 40 |
| 2 | 400 | 30 |
| 3 | 80 | 20 |
| 4 | 50 | 100 |
+------------+------+------+
因此,为了我们的目的,这可以重新排列为...
SELECT product_id
FROM product_filter
GROUP
BY product_id
HAVING MAX(CASE WHEN filter_id = 1 THEN value END) BETWEEN 0 AND 200
AND MAX(CASE WHEN filter_id = 2 THEN value END) BETWEEN 0 AND 50
;
+------------+
| product_id |
+------------+
| 1 |
| 3 |
+------------+
请注意,这不太可能比您多次加入 table 的想法更有效,但它更易于阅读。