Из-за 0 ответов, я предполагаю, что в моем вопросе LEFT JOIN было слишком много деталей о базе данных, которая была слишком эзотерической . Я уже запрограммировал решение этой проблемы, но все же хотел бы знать, как присоединиться к подобному сценарию:
Предположим базовую стратегию суррогатного ключа (каждая таблица имеет поле id, которое просто увеличивается автоматически), а также внешний ключ для своего очевидного родителя. Слова, написанные заглавными буквами, можно рассматривать как таблицы.
Допустим, у вас есть база данных, содержащая DOGS. Пример: Вольфи, Уинстон, Бутч и Бенни
У каждой СОБАКИ есть FLEA. (для простоты давайте сделаем так, чтобы одна блоха жила только на одной собаке, и оставим это отношение 1 ко многим). У блох есть идентификаторы в качестве имен или что-то в этом роде, а также их цвет .
Каждый FLEA укусит своего хозяина DOG несколько раз, и это сохраняется в этой базе данных и записывается ежедневно.
Уинстон, Бутч и Бенни
У каждой СОБАКИ есть FLEA. (для простоты давайте сделаем так, чтобы одна блоха жила только на одной собаке, и оставим это отношение 1 ко многим). У блох есть идентификаторы в качестве имен или что-то в этом роде, а также их цвет .
Каждый FLEA укусит своего хозяина DOG несколько раз, и это сохраняется в этой базе данных и записывается ежедневно.
Уинстон, Бутч и Бенни
У каждой СОБАКИ есть FLEA. (для простоты давайте сделаем так, чтобы одна блоха жила только на одной собаке, и оставим это отношение 1 ко многим). У блох есть идентификаторы в качестве имен или что-то в этом роде, а также их цвет .
Каждый FLEA укусит своего хозяина DOG несколько раз, и это сохраняется в этой базе данных и записывается ежедневно.
Идентификатор полей (PK), идентификатор блохи (FK), дата, times_bitten.
Допустим, вы хотите получить общее количество укусов каждой собаки (это несложно)
SELECT Dog.Name, sum(Bite.times_bitten)
FROM Dog, Flea, Bite
WHERE Dog.id = Flea.Dog_id and Bite.id = Flea.Bite_id
GROUP BY Dog.Name
Допустим, вы должны были добавить критерии к пункт «WHERE», ограничивающий его «коричневыми» блохами, и никакие «коричневые» блохи никогда не кусали Бенни.
SELECT Dog.Name, sum(Bite.times_bitten)
FROM Dog, Flea, Bite
WHERE Dog.id = Flea.Dog_id and Bite.id = Flea.Bite_id and Flea.color = "Brown"
GROUP BY Dog.Name
Бенни отсутствует в результате
Как бы вы переписали запрос так, чтобы имя Бенни все равно отображалось с 0 (желательно) или NULL в сумме, вместо того, чтобы просто полностью исключить Бенни из списка результат?
Похоже, дело в нескольких левых внешних соединениях ... но с несколькими таблицами, подобными этой, документация, которую легко найти, похоже, не отвечает на вопрос, связанный с тремя таблицами с фильтром значений в середине из трех таблиц .
Есть ли у кого-нибудь совет, как переписать это, чтобы разрешить множественные левые внешние соединения, или есть какой-нибудь другой метод сохранения всех имен собак в запросе, даже если сумма = 0?
Это должно работать:
SELECT Dog.Name, COALESCE(SUM(Bite.times_bitten), 0) AS times_bitten
FROM Dog
LEFT JOIN Flea
ON Flea.Dog_id = Dog.id
AND Flea.color = "Brown"
LEFT JOIN Bite
ON Bite.id = Flea.Bite_id
GROUP BY Dog.Name
Используя LEFT JOIN
, вы извлечете все записи Dog, даже те, у которых нет соответствующих Fleas (для которых столбцы из соединения будут NULL). Вы можете использовать COALESCE
, чтобы установить times_bitten
в 0, если записи не найдены (в противном случае это было бы NULL).
Вы, вероятно, также захотите сгруппировать по Dog.id
вместо Dog.Name
(разве невозможно, чтобы было несколько собак с одинаковым именем?)