Yeah, I've been around this merry-go-round a few times. I find that, by explicitly stating my assumptions, I can give the other person feedback on what they did and didn't tell me, avoid confusing the other person with inapplicable advice, and at the same time nail down everything I think is important about the business case. (...which usually keeps me from saying anything TOO stupid...)
The left join is only if you want to make sure that you get an output record for every material, even the ones that never had a record for used or received. If you code SQL using one explicit JOIN, you need to do them all as explicit joins. That would look more or less like this:
Code:
SELECT ProductSub.RawMaterial AS RawMaterial,
SUM ( NZ(ShippingSub.Quantity * ProductSub.Consumption),0)) As RawUsed
FROM
(ProductMain LEFT JOIN
(SELECT ProductSub.ProductNumber,
ProductSub.RawMaterial,
ProductSub.Consumption,
ShippingSub.Quantity,
FROM ProductSub INNER JOIN ShippingSub
ON ProductSub.ProductNumber = ShippingSub.ProductNumber)
ON ProductMain.ProductNumber = ProductSub.ProductNumber)
GROUP BY ProductSub.RawMaterial
then any product that had never been shipped will come back in the list, but with a zero instead of the calculation. I've masked the null as a zero using the NZ function -
Code:
Sum ( NZ(ShippingSub.Quantity * ProductSub.Consumption),0)) As RawUsed
It was more efficient to code that INNER JOIN into a full SELECT clause that returned only the fields that you wanted to see. You could even make it a query in its own right, if you wanted.
But, then again, if the version you've already coded is working, you should just understand the technique described above and move along. There's no sense engaging in serial rewrites while you're on the steep part of the learning curve.