1

我有一个检查记录的废物类型的应用程序。该系统的一部分允许用户预测他们将回收多少废物,并在报告中列出预测的废物类型以及预测的废物数量和已记录的实际废物。

它的工作方式是有一个名为forecastwaste的表和一个名为 的表wastestreamwastestream保存所有关于实际已回收的废物类型的数据,并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

但是,我遇到的问题是,如果在forecastegate 表中存在不在表中的废物类型,则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;

但结果还是一样。它将是返回表中的 NULL 值的theSUM(ws.recordedweight) totalWeight或 the ,但表中将有一个值试图引用它们,但不适用于该值。SUM(ws.percent) totalPercentwastestreamforecasteCOALESCE

4

4 回答 4

1

您需要在 forecastwaste 和 wastetypes 之间建立一个 Inner Join 以及一个到 wastestream 的 Left Join:

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.contractid = '602'替换为(ws.contractid = fw.contractid)作为加入条件。现在不需要在两个地方写contractid,你可以在没有WHERE的情况下运行查询来返回所有行。

编辑:将外部表从废物流更改为预测废物

于 2013-09-16T08:41:45.763 回答
0

根据您的第二次编辑,我建议:

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

这应该通过在总和中使用 COALESCE 来防止空值,并将加入到forecastwaste 中。

于 2013-09-17T19:51:09.583 回答
0

我认为您需要使用联接重写那个,然后您将能够使用 LEFT JOIN。它按您需要的方式工作。

我可以在几分钟内做的事情是这样的:

SELECT ws.wastetype, SUM(ws.recordedweight) totalWeight, SUM(ws.percent) totalPercent, wt.id, wt.category, wt.defrecycling, fw.tonnes 
    FROM wastetypes wt
    LEFT JOIN wastestream ws ON (wt.id = ws.wastetype)
    INNER JOIN forecastwaste fw USING(wt.id = fw.wastetype)
    WHERE wt.contractid = ".$contractid." 
    GROUP BY ws.wastetype

在这里,我假设您需要来自 wt 的信息、关于可能存在于 ws 中的同一类型的信息以及来自 fw 的有关该类型的信息(肯定存在)。我不确定这是否正确,因为我没有要检查的表格,但我想向您展示整个想法。

看看这个问题的答案你会找到解决问题的方法。

于 2013-09-13T23:17:39.113 回答
0

尝试:

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

注意FROM被改成wastetypeswastestream被移到LEFT JOIN并有一个功能COALESCE

于 2013-09-16T08:16:24.350 回答