2013-08-22 2 views
1

나는 제품, 속성 및 product_properties 세 테이블이 있습니다.MySQL 쿼리 여러 조건 및 다중 테이블

가 lens_family에 의해 카메라 1 (일치 카메라와 렌즈에 대한 모든 렌즈를 찾아, 여기에 '표준'입니다 : 여기

products --------------------------------------------- | id | name | description | price | --------------------------------------------- | 1 | Camera | Color Camera | 100 | | 2 | Lens 1 | Camera Lens 1 | 20 | | 3 | Lens 2 | Camera Lens 2 | 30 | --------------------------------------------- properties ------------------------------------------ | id | name | display | ------------------------------------------ | 1 | lens_mount | Lens Mount | | 2 | image_circle | Image Circle | | 3 | focal_length | Focal Length | | 4 | lens_family | Lens Family | ------------------------------------------ product_properties ------------------------------------------------ | id | value | product_id | property_id | ------------------------------------------------ | 1 | F-Mount | 2 | 1 | | 2 | C-Mount | 3 | 1 | | 3 | 42.01 mm | 2 | 2 | | 4 | 13.00 mm | 3 | 2 | | 5 | 10.00 | 2 | 3 | | 6 | 12.00 | 3 | 3 | | 7 | Standard | 1 | 4 | | 8 | Standard | 2 | 4 | | 9 | Standard | 3 | 4 | ------------------------------------------------ 

내 출력 조건 : 테이블 구조와 값의 일부를 아래에서 언급)이 대한 lens_mount = 'F 마운트'와 image_circle> = 40mm 및 focal_length> 5

나는 다음과 같은 시도 쿼리이있는 :

SELECT * FROM products 
    INNER JOIN product_properties ON products.id = product_properties.product_id 
    INNER JOIN properties ON properties.id = product_properties.property_id 
    WHERE (product_properties.value = 'Standard') 
    AND (properties.name = 'lens_mount' AND product_properties.value = 'F-Mount') 
    AND (properties.name = 'image_circle' AND product_properties.value >= ABS('40 mm')) 
    AND (properties.name = 'focal_length' AND product_properties.value >= 5) 

그러나 조건이 하나만있는 경우이 쿼리는 올바른 결과를 제공합니다. 모든 조건에서 어떤 가치도주지 않습니다. OR 대신 AND 대신 AND로 시도했지만 올바른 결과를 얻지는 못했습니다.

아무에게도 이것을 할 수 없습니까? 미리 감사드립니다.

답변

2

당신은 having 절에서보다는 where 절에 논리를 수행 할 : 단일 제품의 속성 세트를 찾고 있습니다

SELECT products.id 
FROM products 
    INNER JOIN product_properties ON products.id = product_properties.product_id 
    INNER JOIN properties ON properties.id = product_properties.property_id 
group by products.id 
having sum(properties.name = 'lens_family' AND product_properties.value = 'Standard') > 0 and 
     sum(properties.name = 'lens_mount' AND product_properties.value = 'F-Mount') > 0 and 
     sum(properties.name = 'image_circle' AND product_properties.value >= ABS('40 mm')) > 0 and 
     sum(properties.name = 'focal_length' AND product_properties.value >= 5) > 0; 

. 모든 조건과 일치 할 수있는 단일 행은 없습니다. 서로 충돌합니다. 대신 group by 절을 사용하여 주어진 제품에 대한 행을 가져와야합니다. 그런 다음 각 조건과 일치하는 행 수를 계산하십시오.

having의 각 절은 sum()으로 묶인 where 문에있는 원래 절 중 하나에 해당합니다. 일치하는 행 수를 계산합니다. 조건은 각 특성에 대해 적어도 하나의 행이 있는지 확인합니다.

+0

나는이 솔루션을 좋아한다. 'Standard'를 값으로 가질 수있는 다른 프로퍼티가있는 경우에는 아마도'properties.name = 'lens_family'AND'를 처음으로'HAVING' 절의 기준 ('product_properties.value = 'Standard'')에 추가해야합니다. – Tom

+0

@Tom. . . 아주 좋은 점. 나는 그 수정을했다. –

+0

고든 & 톰 감사합니다.이 솔루션은 완벽하게 작동했습니다! – Lalu

0

아, 두려운 EVA 스키마. 첫 번째 생각은 다음 SQL에 따라 데이터를 정규화하는보기를 만드는 것입니다.

그런 다음 두 개의 사본을 사용할 수 있습니다 (하나는 카메라 용이고 다른 하나는 렌즈 용). 함께 결합하면 필요한 것을 얻을 수 있습니다.

SELECT p.id 
     ,p.name 
     ,pp1.value as Lens_Mount 
     ,pp2.value as Image_Circle 
     ,pp3.value as Focal_Length 
     ,pp4.value as Lens_Family 
from products p 
left outer join 
     product_properties pp1 
on  pp1.product_id = p.id 
and  pp1.property_id = 1 --lens Mount 
left outer join 
     product_properties pp2 
on  pp2.product_id = p.id 
and  pp2.property_id = 2 --Image Circle 
left outer join 
     product_properties pp3 
on  pp3.product_id = p.id 
and  pp3.property_id = 3 --Focal Length 
left outer join 
     product_properties pp4 
on  pp4.product_id = p.id 
and  pp4.property_id = 3 --Lens Family   
where p.name like 'Lens%' 
0

모든 조건을 충족해야하며 각 product_id에 대해 얼마나 많은 조건이 충족되는지 계산해야합니다. 그래서 GROUP BY product_idHAVING 절을 사용하여 결과를 필터링하십시오.

실제로 숫자 비교가 필요한 경우 문자열 인 속성 값을 비교하는 것이 어려울 수 있습니다.