私は3つのテーブルを持っています。 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');
一部ダミーデータと共に、これらのテーブルの構造は次式で与えられます。 10
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の製品が来るはずです。
第2に、1つのフィルタ(たとえばid = 3)だけがチェックされている場合、このIDに該当するすべての製品をフェッチする必要があります。この状態では、製品id 1、3および4が来る。
フィルタID 2を選択すると、id = 2の製品が1つだけ表示されます。
フィルタ(2及び3)の組み合わせが選択された場合、それらの両方に属しない製品が存在しないため、その後全く製品が来ないであろう。
上記の目標を達成するためにクエリを作成する方法は何ですか?
私は列を含めることに注意してください:PRODUCT_ID、PRODUCT_NAME、filter_idとFILTER_NAMEをテーブルの結果セット内のデータを表示します。
EDIT:フィルタのID 1と3をチェックしたとき
出力は以下と一致する必要があります。
EDIT 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`
しかし、残念ながら、空のセットを返します。どうして?
あなたは '(PRODUCT_ID、filter_id)'の完璧な自然の鍵を持っているようtb_products_to_filters' 'でサロゲートキーは、冗長であることに注意してください。また、SQLのすべてのオブジェクトが(ビューでない限り)テーブルであることを考えると、tb_の接頭辞は不要と思われます(これは個人的な不満です)。 – Strawberry
tb_products_to_filtersの鍵 'id'は冗長ではありません。自動増分された主キーです。他の2列の 'product_id'と' filter_id'は一意の値を持ちません。したがって、このテーブルを操作してさらにクエリするには、 'id'カラムが必要でした。また、 'tb_'接頭辞は不要ではありません。それは個人的な好みです。それは倫理的な命名法です。 WordPressがテーブルの先頭に 'wp_'を付けて同じことをしているのを知らないのですか? – user5307298
これらは組み合わせて考えると一意の値を持ちます。 – Strawberry