我有三个表格, tb_filters,tb_products和tb_products_to_filters。如何查询MySQL中产品和过滤器之间的多对多关系?
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通过复选框选择的页面中,必须从数据库中提取属于过滤器标识1以及过滤标识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`
但不幸的是,它返回一个空集。为什么?
注意,在'tb_products_to_filters'代理键是多余的,因为你有'(产品,过滤器_id)'一个完美的自然键。另外(我承认这是一个个人抱怨),考虑到SQL中的每个对象都是一个表(除非它是一个视图),tb_前缀似乎是不必要的。 – Strawberry
'tb_products_to_filters'中的关键'id'不是多余的。这是一个自动递增的主键。其他两列'product_id'和'filter_id'都没有唯一值。因此'id'列对于操作和进一步查询这个表是必需的。 'tb_'前缀也是不必要的。这是个人偏好。这是一个道德命名法。难道你不知道WordPress为'wp_'添加表吗? – user5307298
它们在组合考虑时具有独特的价值。 – Strawberry