[please forgive formatting errors-- first post here and I tried earnestly to do it right]
Functionally speaking, I'm simply trying to find the items that have the lowest price in its grouping of 'like' items. For example-- there are tons of wines, but I need to find the lowest priced 750ml RED as well as WHITE; there are tons of cheeses, but I need to find the lowest priced 8oz CHEDDAR as well as FETA; etc.
All solutions I've found say to do the same thing I have in my code. There must be a problem with my "self join". The select query on its own runs in less than 10 seconds, and so does the nested select. When I try to join them, though, my query hangs and never finishes. There must be some way to do this join successfully.
I have millions of rows of data I'm pulling from. Each row is a unique item/store combination. My nested select is trying to find the lowest price we have for items that are NOT "name" brand; the lowest price is found among 'like' items, as determined by the columns: store_name, category, subcategory, class, package_desc2, unit_name, chk (in my query, "chk" is determined by the result of two different columns).
This gives me the distinct list of all combinations of the aforementioned columns with the lowest price for each. I'm trying to join THAT to the non "name" brand items to see what the exact item(s) are that have that low price we found in the nested select. Any help is appreciated! I've been at this for days and can't figure it out.
SQL here:
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
You can simplify your code and possibly improve performance by changing your family and pricetype clauses to use IN instead of OR.
For example:
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...
Also, if your subqueries are working as you say they are, you could put them into two different table variables and then join them.