繁体   English   中英

如何在MySQL中查询产品和过滤器之间的多对多关系?

[英]How to query for many to many relationship between products and filters in MySQL?

我有三张桌子即。 tb_filters,tb_products和tb_products_to_filters。 这些表的结构以及一些虚拟数据由下式给出:

tb_filters:

CREATE TABLE IF NOT EXISTS `tb_filters`
(
    `filter_id` INT (11) AUTO_INCREMENT PRIMARY KEY,
    `filter_name` VARCHAR (255)
);

INSERT INTO `tb_filters`
(`filter_name`)
VALUES ('USB'),
('High Speed'),
('Wireless'),
('Ethernet');

在此输入图像描述

tb_products:

CREATE TABLE IF NOT EXISTS `tb_products`
(
    `product_id` INT (11) AUTO_INCREMENT PRIMARY KEY,
    `product_name` VARCHAR (255)
);

INSERT INTO `tb_products`
(`product_name`)
VALUES ('Ohm precision shunt resistor'),
('Orchestrator Libraries'),
('5cm scanner connection'),
('Channel isolated digital'),
('Network Interface Module');

在此输入图像描述

tb_products_to_filters:

CREATE TABLE IF NOT EXISTS `tb_products_to_filters`
(
    `id` INT (11) AUTO_INCREMENT PRIMARY KEY,
    `product_id` INT (11),
    `filter_id` INT (11)
);

INSERT INTO `tb_products_to_filters`
(`product_id`, `filter_id`)
VALUES (1, 1),
(2, 2),
(3, 3),
(4, 3),
(1, 3);

在此输入图像描述

通过查看上面的“tb_products_to_filters”表,我所需的查询是:

当通过页面上的复选框选择过滤器id = 1和3时,必须从数据库中获取属于过滤器ID 1和过滤器ID 3的所有产品。 在这种情况下,应该出现id为1的产品。

其次,当只检查一个过滤器(比如id = 3)时,应该获取属于该id的所有那些产品。 在这种情况下,产品ID 1,3和4将会到来。

如果选择了过滤器ID 2,那么只有一个id = 2的产品会出现。

如果选择过滤器(2和3)的组合,则不会有产品到来,因为没有产品属于它们。

编写查询以获得上述目标的方式是什么?

请注意,我想包括列:product_id,product_name,filter_id和filter_name以显示表结果集中的数据。

编辑:

检查过滤器ID 1和3时,输出应匹配如下:

在此输入图像描述

编辑2:

当我检查过滤器1和3时,我正在尝试下面的查询来获取结果:

SELECT `p`.`product_id`, `p`.`product_name`, 
GROUP_CONCAT(DISTINCT `f`.`filter_id` ORDER BY `f`.`filter_id` SEPARATOR ', ') AS filter_id, GROUP_CONCAT(DISTINCT `f`.`filter_name` ORDER BY `f`.`filter_name` SEPARATOR ', ') AS filter_name 
FROM `tb_products` AS `p` INNER JOIN `tb_products_to_filters` AS `ptf` 
ON `p`.`product_id` = `ptf`.`product_id` INNER JOIN `tb_filters` AS `f` 
ON `ptf`.`filter_id` = `f`.`filter_id` GROUP BY `p`.`product_id` 
HAVING GROUP_CONCAT(DISTINCT `ptf`.`filter_id` SEPARATOR ', ') = ('1,3') 
ORDER BY `p`.`product_id`

但不幸的是,它返回一个空集。 为什么?

您可以在GROUP_CONCAT使用HAVING子句:

SELECT t.product_id,tp.product_name,
       GROUP_CONCAT(t.filter_id) as filter_id,
       GROUP_CONCAT(tb.filter_name) as filter_name
FROM tb_products_to_filters t
INNER JOIN tb_filters tb ON(t.filter_id = tb.filter_id)
INNER JOIN tb_products tp ON(t.product_id = tp.product_id)
WHERE t.filter_id IN(1,3)
GROUP BY t.product_id
HAVING COUNT(distinct t.filter_id) = 2

您可以按照自己的方式进行调整。 请注意,放置在IN()内的参数数量应与COUNT(..) = X

编辑:

在获取这些列时,GROUP_CONCAT中需要DISTINCT关键字,否则所有过滤器都将出现在列表中。 我试着做了

SELECT t.product_id,tp.product_name,
       GROUP_CONCAT(DISTINCT t.filter_id ORDER BY `t`.`filter_id` SEPARATOR ', ') as filter_id,
       GROUP_CONCAT(DISTINCT tb.filter_name ORDER BY tb.filter_name SEPARATOR ', ') as filter_name
FROM tb_products_to_filters t
INNER JOIN tb_filters tb ON(t.filter_id = tb.filter_id)
INNER JOIN tb_products tp ON(t.product_id = tp.product_id)
WHERE t.filter_id IN(1,3)
GROUP BY t.product_id
HAVING COUNT(distinct t.filter_id) = 2

但仍然所有过滤器名称(以太网,高速,USB,无线)都在列表中。 如何只列出那些对应的过滤器id(1,3)在字符串中的过滤器名称?

在此输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM