I've an application that checks recorded waste types. Part of the system allows the user to forecast how much waste they will recycle, and in a report it will list the forecasted waste type with how much was forecast and the actual waste that's been recorded.
The way it works it out is that there is one table called forecastwaste and a table called wastestream. wastestream holds all of the data about waste types that actually have been recycled, and forecastwaste holds the waste types that have been forecast. The wastetypes table holds the name of the available wastetypes that the user can choose from.
I have this SQL Statement ($contractid contains the id of the contract):
SELECT ws.wastetype, SUM(ws.recordedweight) totalWeight, SUM(ws.percent) totalPercent, wt.id, wt.category, wt.defrecycling, fw.tonnes
FROM wastestream ws, wastetypes wt, forecastwaste fw
WHERE ws.contractid = ".$contractid."
AND fw.contractid = ".$contractid."
AND ws.wastetype = wt.id
AND fw.wastetype = wt.id
GROUP BY ws.wastetype
However, the problem I have is that if there is a waste type in the forecastewate table that isn't in the wastestream table the query won't display anything. I want to get it so that if no results can be found in the wastestream table, the query will still display the forecastewaste record and return 0 if it can't find anything. The current query doesn't allow this.
How can I make the query work so that it does what I need it to?
EDIT
Thanks to Bandydan I've rewritten the query so it now looks like this:
SELECT ws.wastetype, SUM(ws.recordedweight) totalWeight, SUM(ws.percent) totalPercent, wt.id, wt.category, wt.defrecycling, fw.tonnes
FROM c1skips.wastestream ws
LEFT JOIN c1skips.wastetypes wt ON (wt.id = ws.wastetype)
INNER JOIN c1skips.forecastwaste fw ON (wt.id = fw.wastetype)
WHERE fw.contractid = '602'
AND ws.contractid = '602'
GROUP BY ws.wastetype;
I will explain what I'm trying to do a bit better too.
I have a table called forecastwaste and in that table I have the following data:
|---------------------------------|
| wastetype | tonnes | contractid |
|-----------|--------|------------|
| 1 | 10 | 602 |
| 2 | 20 | 602 |
| 3 | 50 | 602 |
|-----------|--------|------------|
This table is then used to look at the wastestream table so see how much of the material is recycled. The wastestream table looks like this:
|-----------------------------------------|
| wastetype | recordedweight | contractid |
|-----------|----------------|------------|
| 1 | 2 | 602 |
| 1 | 4 | 602 |
| 2 | 20 | 602 |
|-----------|----------------|------------|
Both tables reference the wastetype table, which identifies the number with a waste type.
With the current query, it will only return the results if they show up in the wastestream table. However, I want it so that even if there isn't a record in the wastestream table it will return 0.
EDIT 2
I've added COALESCE to my query like this:
SELECT ws.wastetype, SUM(ws.recordedweight) totalWeight, SUM(ws.percent) totalPercent, wt.id, wt.category, wt.defrecycling,
COALESCE(ws.recordedweight, 0) tonnes
FROM c1skips.wastestream ws
LEFT JOIN c1skips.wastetypes wt ON (wt.id = ws.wastetype)
INNER JOIN c1skips.forecastwaste fw ON (wt.id = fw.wastetype)
WHERE fw.contractid = '602'
AND ws.contractid = '602'
GROUP BY ws.wastetype;
But the results are still the same. It's going to be either the SUM(ws.recordedweight) totalWeight or the SUM(ws.percent) totalPercent that return the NULL values in the wastestream table but there will be a value in the forecaste table trying to reference them, but COALESCE won't work with that.