2012-01-26 1 views
1

는 [여기 errors-- 첫 번째 게시물의 서식을 용서하십시오 나는 그것을 할 열심히 노력 우측] SQL Server를 사용하면 동일한 테이블의 모든 '유사한'레코드의 최소값으로 레코드를 조인 할 수 있습니까?

기능적으로, 나는 단순히 항목 '처럼'의 그 그룹에서 가장 낮은 가격을 가지고있는 아이템을 찾기 위해 노력하고있어 말하기 . 예를 들어, 톤의 와인이 있지만, 가장 저렴한 750ml RED와 WHITE를 찾아야합니다. 거기에 톤의 치즈가 있지만, 나는 FETA뿐만 아니라 가장 저렴한 8 온스 CHEDDAR를 찾아야합니다;

내가 발견 한 모든 해결책은 내가 가지고있는 것과 동일한 일을한다고 말합니다. "자기 조인"에 문제가 있어야합니다. 자체 쿼리는 10 초 이내에 실행되며 중첩 된 선택도 실행됩니다. 하지만 내가 가입하려고하면 내 쿼리가 멈추고 끝나지 않습니다.이 조인을 성공적으로 수행하는 방법이 있어야합니다.

저는 수백만 행의 데이터를 가져 왔습니다. 각 행은 고유 항목/상점 조합입니다. 내 중첩 된 선택 항목은 "이름"브랜드가 아닌 항목에 대해 가장 낮은 가격을 찾고 있습니다. store_name, category, subcategory, class, package_desc2, unit_name, chk (내 쿼리에서 "chk"는 두 개의 다른 열 결과에 의해 결정됨) 열에 의해 결정되는 'like'항목 중 최저 가격이 발견됩니다.

이렇게하면 앞서 언급 한 열의 모든 조합에 대해 고유 한 최저 가격의 목록을 얻을 수 있습니다. 나는 "이름"이 아닌 브랜드 항목에 THAT를 결합하여 정확한 항목이 우리가 중첩 된 선택에서 찾은 저렴한 가격을 가지고 있는지 확인하려고합니다. 어떤 도움을 주셔서 감사합니다! 나는이 일을 며칠 동안 해왔고 그것을 이해할 수 없다. 여기

SQL :

SELECT b.zone_name, 
     b.store_name, 
     b.family, 
     b.category, 
     b.subcategory, 
     b.class, 
     b.team, 
     b.subteam, 
     b.pos_dept, 
     b.brand_name, 
     b.item_description, 
     b.upc, 
     b.package_desc1   pkg, 
     b.package_desc2   sz, 
     b.unit_name, 
     CASE 
     WHEN b.good = 'good' 
       OR b.how_good = 1 THEN 'YES' 
     ELSE 'NO' 
     END      AS chk, 
     b.eff_pricetype, 
     b.eff_price    low_price, 
     b.cd     dollar_sales, 
     b.cu     unit_sales, 
     b.cgm     margin_dollars, 
     b.cgm/Nullif(b.cd, 0) AS margin_pct, 
     b.deleted_item, 
     b.discontinue_item, 
     b.not_available, 
     b.remove_item, 
     b.recall_flag, 
     CASE 
     WHEN 
SUM( 
Isnull(b.deleted_item, 0) + Isnull(b.discontinue_item, 0) + Isnull(b.not_available, 0) + Isnull(b.remove_item, 0) + Isnull(b.recall_flag, 0)) = 0 THEN 
     'NO' 
    ELSE 'YES' 
END      AS istatus, 
d.low 
FROM mytable b 
     INNER JOIN(SELECT c.store_name, 
         c.category, 
         c.subcategory, 
         c.class, 
         c.package_desc2, 
         c.unit_name, 
         CASE 
          WHEN c.good = 'good' 
           OR c.how_good = 1 THEN 'YES' 
          ELSE 'NO' 
         END    AS chk, 
         MIN(c.eff_price) low 
        FROM mytable c 
        WHERE store_name = 'some store' 
         AND brand_name NOT LIKE '%name%' 
         AND weeks = 'Last 12 weeks' 
         AND (eff_pricetype = 'REG' 
           OR eff_pricetype = 'EDV' 
           OR eff_pricetype = 'GBC' 
           OR eff_pricetype = 'CMP' 
           OR eff_pricetype = 'LIN' 
           OR eff_pricetype = 'FRZ' 
           OR eff_pricetype = 'GBB' 
           OR eff_pricetype = 'EDLP' 
           OR eff_pricetype = 'GBN' 
           OR eff_pricetype = 'GBR' 
           OR eff_pricetype = 'MKT' 
           OR eff_pricetype = 'COMP' 
           OR eff_pricetype = 'R' 
           OR eff_pricetype = 'COM') 
         AND (family = 'carrots' 
           OR family = 'tomatoes' 
           OR family = 'Cheese' 
           OR family = 'Coffee' 
           OR family = 'peppers' 
           OR family = 'milk' 
           OR family = 'oil' 
           OR family = 'season' 
           OR family = 'Housewares' 
           OR family = 'paper' 
           OR family = 'Meat' 
           OR family = 'soup' 
           OR family = 'nuts' 
           OR family = 'pizza' 
           OR family = 'potatoes' 
           OR family = 'Seafood' 
           OR family = 'beer' 
           OR family = 'vitamins' 
           OR family = 'Tea' 
           OR family = 'Wine' 
           OR family = 'beans') 
        GROUP BY c.store_name, 
          c.category, 
          c.subcategory, 
          c.class, 
          c.package_desc2, 
          c.unit_name, 
          c.good, 
          c.how_good 
        HAVING MIN(c.eff_price) > 0) AS d 
     ON b.store_name = d.store_name 
      AND b.category = d.category 
      AND b.subcategory = d.subcategory 
      AND b.class = d.class 
      AND b.package_desc2 = d.package_desc2 
      AND b.unit_name = d.unit_name 
      AND CASE 
        WHEN b.good = 'good' 
         OR b.how_good = 1 THEN 'YES' 
        ELSE 'NO' 
       END = d.chk 
      AND b.eff_price = d.low 
WHERE store_name = 'some store' 
     AND brand_name NOT LIKE '%name%' 
     AND weeks = 'Last 12 weeks' 
     AND (eff_pricetype = 'REG' 
       OR eff_pricetype = 'EDV' 
       OR eff_pricetype = 'GBC' 
       OR eff_pricetype = 'CMP' 
       OR eff_pricetype = 'LIN' 
       OR eff_pricetype = 'FRZ' 
       OR eff_pricetype = 'GBB' 
       OR eff_pricetype = 'EDLP' 
       OR eff_pricetype = 'GBN' 
       OR eff_pricetype = 'GBR' 
       OR eff_pricetype = 'MKT' 
       OR eff_pricetype = 'COMP' 
       OR eff_pricetype = 'R' 
       OR eff_pricetype = 'COM') 
     AND (family = 'carrots' 
       OR family = 'tomatoes' 
       OR family = 'Cheese' 
       OR family = 'Coffee' 
       OR family = 'peppers' 
       OR family = 'milk' 
       OR family = 'oil' 
       OR family = 'season' 
       OR family = 'Housewares' 
       OR family = 'paper' 
       OR family = 'Meat' 
       OR family = 'soup' 
       OR family = 'nuts' 
       OR family = 'pizza' 
       OR family = 'potatoes' 
       OR family = 'Seafood' 
       OR family = 'beer' 
       OR family = 'vitamins' 
       OR family = 'Tea' 
       OR family = 'Wine' 
       OR family = 'beans') 
GROUP BY b.zone_name, 
      b.store_name, 
      b.family, 
      b.category, 
      b.subcategory, 
      b.class, 
      b.team, 
      b.subteam, 
      b.pos_dept, 
      b.brand_name, 
      b.item_description, 
      b.upc, 
      b.package_desc1, 
      b.package_desc2, 
      b.unit_name, 
      d.org, 
      b.eff_pricetype, 
      b.eff_price, 
      b.cd, 
      b.cu, 
      b.cgm, 
      b.deleted_item, 
      b.discontinue_item, 
      b.not_available, 
      b.remove_item, 
      b.recall_flag, 
      d.low, 
      b.good, 
      b.how_good 
+0

테이블 구조와 인덱스를 제공 할 수 있습니까? 또한 데이터 구조는 문제가 있으며 결코 수행되지 않을 가능성이 큽니다. 상점은 자체 테이블이어야하며, 카테고리와 하위 카테고리, 가족 및 eff_pricetype을 구성하는 방법에 따라 달라야합니다. – Luis

+0

네, 힘들어요. reg_data_cube는 실제로 인덱스가없는 뷰입니다. 뷰를 구성하는 테이블에는 자체 인덱스가 있지만보기에만 액세스 할 수 있으며 변경할 수는 없습니다. : –

+0

설명을 확인하십시오. 그러나 색인 없이는 개선 할 수있는 방법이 많지 않다고 생각합니다. – Luis

답변

1

당신은 당신의 코드를 단순화 가능성이 가족과 pricetype 절 대신 OR의에서 사용할 변경하여 성능을 향상시킬 수 있습니다. 예를 들어

:

또한
AND eff_pricetype IN ('REG','EDV','GBC','CMP','LIN','FRZ', 
         'GBB','EDLP','GBN','GBR','MKT','COMP','R','COM') 

    AND family IN ('carrots','tomatoes','Cheese','Coffee', etc... 

, 당신은 그들이 말하는대로 하위 쿼리가 작업하는 경우, 당신은 두 개의 서로 다른 테이블 변수에 넣어 한 다음에 가입 할 수있다.

+0

답장을 보내 주셔서 감사합니다! 표 변수를 사용하여 알려주겠습니다. –

+0

실제로 사용했습니다. 임시 테이블 및 기본 키로 그냥 행 번호를 반영했다 ID 열 추가했습니다. 그것은 14 초 안에 실행했습니다. 감사합니다! –