2013-04-14 2 views
0

GROUP BY와 함께 사용되는 MySQL MIN()에서 발생하는 문제에 대한보다 우아한 해결책을 찾고 있습니다. 나는 각 금속의 그룹에서 가장 저렴한 금속을 선택하고자하는SQL MIN() & GROUP BY

  1. 제품 (ID, GROUP_ID)
  2. product_attributes (PRODUCT_ID,은 attribute_id, 값)

:

나는 두 개의 테이블이 (attribute_id = 40) 특정 제품 그룹에서.

다음 쿼리는 작동하지만 훨씬 더 잘 작성되었을 수 있습니다.

SELECT metal.product_id, metal.value AS `metal`, `price`.value AS `price` 
FROM 
    product_attributes metal 
INNER JOIN 
    (
     SELECT metal.value AS `metal`, MIN(price.value) AS `price` 
     FROM 
      product_attributes metal 
     LEFT JOIN 
      product_attributes price 
     ON metal.product_id = price.product_id 
     INNER JOIN products p 
     ON p.id = metal.product_id 
     WHERE 
      metal.attribute_id = 40 AND 
      price.attribute_id = 37 AND 
      p.group_id = 1 
     GROUP BY 
      metal.value 
     ORDER BY metal ASC, price DESC 
    ) AS d ON 
    d.metal = metal.value 
LEFT JOIN 
    product_attributes price ON 
    metal.product_id = price.product_id AND price.attribute_id = 37 
INNER JOIN 
    products p ON 
    p.id = metal.product_id 
WHERE 
    metal.attribute_id = 40 
    AND d.price = price.value 
    AND p.group_id = 1 
GROUP BY 
    metal.value 
ORDER BY 
    metal.value ASC, 
    price.value DESC; 

답변

0

결국 솔루션은 나보다 간단합니다. 내부 쿼리에서 데이터를 가격순으로 주문 했으므로 GROUP BY보다 먼저 정렬을 수행해야합니다. 이렇게하면 각 금속 그룹에서 가장 저렴한 제품을 얻을 수 있습니다.

SELECT * FROM 
      (
       SELECT metal.enum_id AS `metal`, metal.product_id FROM product_attributes metal 
       LEFT JOIN product_attributes price ON metal.product_id = price.product_id AND price.attribute_id = 37 
       INNER JOIN products p ON p.id = metal.product_id 
       WHERE 
        metal.attribute_id = 40 AND 
        p.group_id = 1 AND 
        p.id NOT IN (SELECT DISTINCT product_id FROM product_attributes WHERE (attribute_id=162 OR attribute_id=204 OR attribute_id=205) AND `value`=1) 
       ORDER BY price.value+'0' ASC 
      ) AS s 
      GROUP BY metal 
0

난 당신이 단지 group by 문으로 이것을 할 수 있다고 생각 :

SELECT metal.value AS `metal`, metal.product_id, MIN(price.value) AS `price` 
    FROM product_attributes metal LEFT JOIN 
     product_attributes price 
     ON metal.product_id = price.product_id 
     INNER JOIN products p 
     ON p.id = metal.product_id 
    WHERE metal.attribute_id = 40 AND 
     price.attribute_id = 37 AND 
     p.group_id = 1 
    GROUP BY metal 
    order by metal, price 

metal.value 당 하나의 product_id이 있다고 가정 작동합니다. 여러 개의 같은 제품 ID가있는 경우에, 당신은 속성 테이블에 다시 가입해야합니다 :

SELECT metal.product_id, metal.value AS `metal`, d.`price` 
FROM (SELECT metal.value AS `metal`, MIN(price.value) AS `price` 
     FROM product_attributes metal LEFT JOIN 
      product_attributes price 
      ON metal.product_id = price.product_id 
      INNER JOIN products p 
      ON p.id = metal.product_id 
     WHERE metal.attribute_id = 40 AND 
      price.attribute_id = 37 AND 
      p.group_id = 1 
     GROUP BY metal 
    ) d join 
    product_attributes metal 
    ON d.metal = metal.value 
ORDER BY metal.value ASC, d.price DESC 

그것은 당신이 또한 where을해야 할 수도 있습니다 가능성이 추가 조인. 이는 데이터 구조에 따라 다릅니다.