2016-08-18 3 views
4

나는 세 개의 테이블 즉. 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'); 

enter image description here

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'); 

enter image description here

,536,913,632 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); 

enter image description here

테이블 위의 "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 열을 포함하고 싶습니다.

편집 :

출력은 필터 IDS 1과 3이 선택되었을 때 다음과 일치해야합니다 :

enter image description here

편집 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` 

하지만 불행히도 빈 세트를 반환합니다. 왜?

+0

참고. 또한 SQL의 모든 객체가 테이블이라는 사실을 감안할 때 tb_ 접두어는 불필요한 것처럼 보입니다 (개인적인 불만이 있음을 인정합니다). – Strawberry

+0

tb_products_to_filters의 key id가 중복되지 않습니다. 자동 증가 기본 키입니다. 다른 두 열'product_id'와'filter_id'는 고유 한 값을 가지고 있지 않습니다. 따라서이 테이블을 더 조작하고 쿼리하기 위해서는'id' 컬럼이 필요했습니다. 또한'tb_' 접두사는 불필요하지 않습니다. 개인적인 취향입니다. 그것은 윤리적 인 명명법입니다. 워드 프레스가'wp_'라는 접두어로 접두어를 붙이는 것을 알고 계십니까? – user5307298

+0

조합으로 고려하면 고유 한 값을 갖습니다. – Strawberry

답변

2

당신은 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 필요합니다. 나는 그것을 시도했다

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)가 문자열에있는 필터 이름 만 나열하는 방법? 당신이 (PRODUCT_ID, filter_id)``에 완벽하게 좋은 자연 키를 가지고 tb_products_to_filters``의 대용 키가 중복이라고

enter image description here

+0

검색어가 잘못되었습니다. '# 1054 - 'having clause'에 't.product_filter'열이 없습니다. – user5307298

+0

내 질문이 업데이트되었습니다. 나는 모든 칼럼을 원해. 그래서 내가 처음으로 2 개의 테이블을 필요로하지 않는다고 말하는 것은 잘못되었습니다. – user5307298

+0

@ user5307298 자신 만의 노력을하고 다음 번에는 자신을 더 잘 설명하십시오. 쿼리가 지금 업데이트됩니다. – sagi

관련 문제