У меня есть приложение, которое проверяет зарегистрированные типы отходов. Часть системы позволяет пользователю прогнозировать, сколько отходов они будут перерабатывать, а в отчете будет перечисляться прогнозный тип отходов с учетом того, сколько было прогнозировано, и фактических отходов, которые были зарегистрированы.Извлечь все записи из одной таблицы, даже если связанная запись не найдена в связанной таблице
Способ, которым он работает, состоит в том, что существует одна таблица под названием forecastwaste
и таблица с именем wastestream
. wastestream
содержит все данные о типах отходов, которые фактически были переработаны, а forecastwaste
содержит типы отходов, которые были предсказаны. Таблица wastetypes
содержит имя доступных типов wastetypes, которые пользователь может выбрать.
У меня есть этот SQL Statement ($contractid
содержит идентификатор контракта):
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
результатов не было найдено, запрос будет по-прежнему отображать запись прогноза и возвращать 0
, если он ничего не может найти. Текущий запрос не позволяет этого.
Как я могу заставить запрос работать так, чтобы он выполнял то, что мне нужно?
EDIT
Благодаря 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.
EDIT 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) totalWeight
, либо SUM(ws.percent) totalPercent
, которые возвращают значения NULL в таблице wastestream
, но в таблице forecaste
будет указано значение, пытающееся ссылаться на них, но COALESCE
не будет работать с этим.
Рассмотрите возможность первой замены этого оператора на тот, который использует INNER JOINs для упрощения чтения. Тогда это вопрос использования LEFT JOIN. –