我有一个检查记录垃圾类型的应用程序。系统的一部分允许用户预测他们将回收多少废物,并在报告中列出预测的废物类型以及预测的数量和实际记录的废物。
它的工作方式是有一个名为forecastwaste的表和一个名为wastestream的表。wastestream包含关于实际回收的废物类型的所有数据,forecastwaste包含已预测的废物类型。wastetypes表包含用户可以从中选择的可用废物类型的名称。
我有这个SQL语句($contractid包含合同的id):

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

但是,我遇到的问题是,如果forecastewate表中有一个废物类型不在wastestream表中,那么查询将不会显示任何内容。我想获取它,以便如果在wastestream表中找不到结果,查询仍将显示forecastewaste记录,如果找不到任何结果,则返回0。当前查询不允许这样做。
我怎样才能使查询正常工作,以便它完成我需要的工作?
编辑
多亏了Bandydan,我重写了查询,所以现在看起来像这样:
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;

我也会解释我想做的更好。
我有一个名为forecastwaste的表,在该表中,我有以下数据:
|---------------------------------|
| wastetype | tonnes | contractid |
|-----------|--------|------------|
|     1     |   10   |    602     |
|     2     |   20   |    602     |
|     3     |   50   |    602     |
|-----------|--------|------------|

然后使用此表查看wastestream表,以查看回收了多少材料。wastestream表如下所示:
|-----------------------------------------|
| wastetype | recordedweight | contractid |
|-----------|----------------|------------|
|     1     |       2        |     602    |
|     1     |       4        |     602    |
|     2     |      20        |     602    |
|-----------|----------------|------------|

两个表都引用wastetype表,该表用废物类型标识数字。
对于当前查询,只有结果出现在wastestream表中时,它才会返回结果。但是,我希望这样,即使wastestream表中没有记录,它也将返回0。
编辑2
我已将COALESCE添加到查询中,如下所示:
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;

但结果还是一样。将是SUM(ws.recordedweight) totalWeightSUM(ws.percent) totalPercent返回wastestream表中的空值,但是forecaste表中会有一个值试图引用它们,但是COALESCE无法使用。

最佳答案

在forecastwaste和wastetypes之间需要一个内部连接,再加上wastestream的左连接:

SELECT ws.wastetype, SUM(ws.recordedweight) totalWeight, SUM(ws.percent) totalPercent, wt.id, wt.category, wt.defrecycling, fw.tonnes
FROM c1skips.forecastwaste fw
JOIN c1skips.wastetypes wt ON (wt.id = fw.wastetype)
LEFT JOIN c1skips.wastestream ws
ON (ws.contractid = fw.contractid) AND (ws.wastetype = fw.wastetype)
WHERE fw.contractid = '602'
GROUP BY ws.wastetype;

我将fw.compressd='602'替换为(ws.compressd=fw.compressd)作为连接条件。现在不需要在两个地方编写压缩,您可以运行查询而不返回所有行。
编辑:将外部表从wastestream更改为forecastwaste

关于mysql - 从一个表中检索所有记录,即使在相关表中找不到相关记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18796434/

10-16 16:37