Я бы посоветовал вам не присоединяться к таким столам. Как я уже сказал в своем комментарии к ответу StieveG, при объединении таблиц таким образом вы можете получить то, что иногда называют мини- декартовым произведением . Вот иллюстрированное объяснение на тот случай, если оно вам понадобится.
Например, у вас есть 2 строки в training_room
, соответствующие строке в training
, и 3 строки в training_teacher
, соответствующие одной и той же строке training
. Сначала объединяется таблица комнаты, и в результате мы получаем два ряда для указанной тренировки. Они содержат две отдельные комнаты, но помните, что они также содержат одинаковое обучение, дублированное.
Почему это важно? Потому что последующее соединение с training_teacher
выполняется не только с таблицей тренировок, а с результатом соединения из training
с training_room
. Просто бывает, что условие соединения содержит только столбец из training
, но столбец будет взят из предыдущего объединения, а не из таблицы.
Итак, вы будете сопоставлять с каждым из дублированных тренингов, и за каждый вы получите еще три, по количеству совпадающих учителей.
Таким образом, в результате одного тренинга будет получено 6 рядов, в которых 2 комнаты будут повторяться 3 раза, а 3 учителя будут повторяться дважды. Соответственно, оба СЧЕТА вернут 6
.
Одним из возможных решений может быть простое изменение выражений COUNT следующим образом:
…
COUNT (DISTINCT t_r.id),
COUNT (DISTINCT t_t.id)
…
Это не помешает объединениям производить декартовы произведения, но, по крайней мере, результаты будут последовательными (при условии, что на тренинге никогда не может быть двухместных комнат или учителей).
Но на вашем месте я, вероятно, решил бы это по-другому, сгруппировав подвыборы и присоединив таблицу training
к результатам подвыборов, например:
SELECT
t.id,
t.town,
IFNULL(tr.cnt) AS room_count,
IFNULL(tt.cnt) AS teacher_count
FROM training AS t
LEFT JOIN (
SELECT
id_training,
COUNT(*) AS cnt
FROM training_room
WHERE enabled = 'true'
GROUP BY id_training
) AS tr ON t.id = tr.id_training
LEFT JOIN (
SELECT
id_training,
COUNT(*) AS cnt
FROM training_teacher
WHERE enabled = 'true'
GROUP BY id_training
) AS tt ON t.id = tt.id_training
WHERE t.town = 'X'