使用SQL Server,如何将记录连接到同一个表中所有“类似”记录的最小值?

时间:2012-01-26 22:49:23

标签: sql sql-server join inner-join minimum

[请原谅格式错误 - 首先发布在这里,我努力做正确的事情]

从功能上讲,我只是想在“喜欢”项目的分组中找到价格最低的商品。例如 - 有大量的葡萄酒,但我需要找到价格最低的750毫升RED和WHITE;有大量的奶酪,但我需要找到价格最低的8盎司CHEDDAR以及FETA;等

我发现的所有解决方案都说我在代码中执行相同的操作。 我的“自我加入”一定有问题。选择查询本身在不到10秒的时间内运行,嵌套选择也是如此。但是,当我尝试加入它们时,我的查询会挂起并且永远不会完成。必须有一些方法才能成功加入。

我有数百万行数据。每行都是唯一的商品/商店组合。我的嵌套选择试图找到我们对非“名牌”品牌的最低价格;在'like'项目中找到最低价格,由列确定:store_name,category,subcategory,class,package_desc2,unit_name,chk(在我的查询中,“chk”由两个不同列的结果确定)。 / p>

这为我提供了上述列的所有组合的清晰列表,每个列的价格最低。我正在尝试加入非“名称”品牌商品,看看具有我们在嵌套选择中找到的低价格的确切商品。任何帮助表示赞赏!我已经好几天了,无法理解。

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 

1 个答案:

答案 0 :(得分:1)

您可以通过更改族和pricetype子句来使用IN而不是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...

此外,如果您的子查询正如您所说的那样工作,则可以将它们放入两个不同的表变量中,然后将它们连接起来。