Происходит следующее: каждая строка, возвращенная из дочерней таблицы, сопоставляется с каждой строкой, возвращенной из других дочерних таблиц.
Как и ожидалось, возвращена одна родительская строка.
Но если одна из дочерних таблиц имеет семь (7) совпадающих строк, а другая дочерняя таблица имеет девять (9) совпадающих строк, вы получите 7 * 9 = 63 возвращенных строк.
Это ожидаемый набор результатов, согласно спецификации SQL.
Вот тестовый пример, который демонстрирует, что происходит:
CREATE TABLE t (id INT);
CREATE TABLE c1 (id INT, t_id INT);
CREATE TABLE c2 (id INT, t_id INT);
INSERT INTO t VALUES (1);
INSERT INTO c1 VALUES (11,1),(12,1);
INSERT INTO c2 VALUES (21,1),(22,1);
SELECT t.id, c1.id AS c1, c2.id AS c2
FROM t
JOIN c1 ON (t.id = c1.t_id)
JOIN c2 ON (t.id = c2.t_id)
id c1 c2
-- --- ---
1 11 21
1 12 21
1 11 22
1 12 22
Обратите внимание, что строки из c1 повторяются, один раз для каждой строки из c2. Аналогично для строк из c2.
Это именно тот набор результатов, который мы ожидаем.
Если мы не хотим перекрестного соединения (декартово произведение) дочерних строк, мы можем запустить отдельные запросы:
SELECT t.id, c1.id AS c1
FROM t
JOIN c1 ON (t.id = c1.t_id)
SELECT t.id, c2.id AS c2
FROM t
JOIN c2 ON (t.id = c2.t_id)
id c1
-- ---
1 11
1 12
id c2
-- ---
1 21
1 22
Это один из способов избежать генерации «повторяющихся» дочерних строк.