programing

이 SQL 쿼리는 어떻게 동일한 id_product로 결과를 반환합니까?

telecom 2023. 8. 13. 09:32
반응형

이 SQL 쿼리는 어떻게 동일한 id_product로 결과를 반환합니까?

일부 코드에서 중복 없이 제품을 반환해야 하는 복잡한 SQL 쿼리에 직면했습니다(처음에 DISTINCT 키워크를 사용하여). 다음 쿼리가 있습니다.

SELECT DISTINCT p.`id_product`, p.*, product_shop.*, pl.* , m.`name` AS manufacturer_name, x.`id_feature` , x.`id_feature_value`  , s.`name` AS supplier_name
FROM `ps_product` p
    INNER JOIN ps_product_shop product_shop
        ON (product_shop.id_product = p.id_product AND product_shop.id_shop = 1)
    LEFT JOIN `ps_product_attribute` y ON (y.`id_product` = p.`id_product`) 
    LEFT JOIN `ps_product_attribute_combination` ac ON (y.`id_product_attribute` = ac.`id_product_attribute`) 
    LEFT JOIN `ps_product_lang` pl ON (p.`id_product` = pl.`id_product`  AND pl.id_shop = 1 )
    LEFT JOIN `ps_manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
    LEFT JOIN `ps_feature_product` x ON (x.`id_product` = p.`id_product`)
    LEFT JOIN `ps_supplier` s ON (s.`id_supplier` = p.`id_supplier`)
    LEFT JOIN `ps_category_product` c ON (c.`id_product` = p.`id_product`)
WHERE pl.`id_lang` = 1 AND c.`id_category` = 18 AND  p.`price` between 0 and 1000
  AND product_shop.`visibility` IN ("both", "catalog") AND product_shop.`active` = 1
ORDER BY p.`id_product` ASC LIMIT 1,4

하지만 "id_product"가 같은 제품 2개로 4개 제품을 반품합니다(11941)

제가 필요한 것은 각각 다른 ID의 제품 4개를 반품하는 것입니다.

누구라도 있나요?

정말 감사해요.

에어믹

[편집]

이 쿼리의 결과는 4개의 행을 나타내며, 2개의 은 id_feature_value 열을 제외하고 동일한 열 값을 가집니다(한 행은 36개, 다른 열은 38개).

SELECT DISTINCT첫 번째 필드뿐만 아니라 쿼리에서 선택한 모든 필드의 고유한 조합을 모두 가져옵니다.

이제 GROUP BY를 사용하여 다음과 같이 id_product의 고유한 값만 선택하여 이 문제를 해결할 수 있습니다.

SELECT p.`id_product`, p.*, product_shop.*, pl.* , m.`name` AS manufacturer_name, x.`id_feature` , x.`id_feature_value`  , s.`name` AS supplier_name
FROM `ps_product` p
    INNER JOIN ps_product_shop product_shop
        ON (product_shop.id_product = p.id_product AND product_shop.id_shop = 1)
    LEFT JOIN `ps_product_attribute` y ON (y.`id_product` = p.`id_product`) 
    LEFT JOIN `ps_product_attribute_combination` ac ON (y.`id_product_attribute` = ac.`id_product_attribute`) 
    LEFT JOIN `ps_product_lang` pl ON (p.`id_product` = pl.`id_product`  AND pl.id_shop = 1 )
    LEFT JOIN `ps_manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
    LEFT JOIN `ps_feature_product` x ON (x.`id_product` = p.`id_product`)
    LEFT JOIN `ps_supplier` s ON (s.`id_supplier` = p.`id_supplier`)
    LEFT JOIN `ps_category_product` c ON (c.`id_product` = p.`id_product`)
WHERE pl.`id_lang` = 1 AND c.`id_category` = 18 AND  p.`price` between 0 and 1000
  AND product_shop.`visibility` IN ("both", "catalog") AND product_shop.`active` = 1
GROUP BY p.`id_product`
ORDER BY p.`id_product` ASC LIMIT 1,4

그러나 이제 문제는 사용자가 선택한 다른 모든 필드의 여러 다른 값이 쿼리에서 선택할 수 있는 결정적인 방법이 없다는 것입니다.id_product는 테이블에서 고유하지만 결과 집합에서 고유하지 않습니다. 적어도 하나의 JOIN에는 1대 다 관계가 있기 때문입니다. 즉, JOIN 조건과 일치하는 여러 행이 있습니다.

MySQL의 이전 버전에서는 이 경우 발견된 첫 번째 값을 선택하기만 하지만 SQL Server에서는 실제로 오류가 발생하여 GROUP BY 절에 나머지 필드가 언급되거나 집계되어야 한다고 알려줍니다.다음과 같은 몇 가지 방법이 있습니다.

  1. 이전 버전의 MySQL에 있으며 나머지 필드에 대해 반환되는 값은 특별히 신경 쓰지 않으므로 쿼리는 내가 게시한 대로 남겨 두고 사용하십시오.이것은 정의되지 않은 행동이기 때문에 이론적으로 MySQL의 변덕에 따라 바뀔 수 있기 때문에 추천하지 않을 것입니다.그러나 반환되는 모든 값은 동일한 결과 행에서 반환됩니다.
  2. 선택 절의 나머지 필드에 MIN() 또는 MAX()와 같은 집계 함수를 추가합니다.이렇게 하면 필드의 가능한 값이 하나로 줄어들지만 다른 행의 값이 혼합될 수 있습니다.
  3. 쿼리에서 1대 다 JOIN을 제거하여 각 id_product에 대한 결과 집합에서 하나의 행만 반환되도록 합니다.그런 다음 필요한 나머지 데이터를 별도의 쿼리로 가져옵니다.

다른 대안 솔루션이 있을 수 있지만 나머지 행에 대해 반환할 값과 RDB에 따라 크게 달라집니다.사용 중인 MS.예를 들어 SQL Server에서 PARTITION BY를 사용하여 고유한 각 id_product의 첫 번째 행을 결정적으로 선택할 수 있습니다.

언급URL : https://stackoverflow.com/questions/58011029/how-does-this-sql-query-return-results-with-same-id-product

반응형