2016-02-16 2 views
1

Используя следующую базу данных с 3 таблицами в MySQL и следующий запрос, результат всегда является декартовым продуктом. Вместо этого я хочу получить прямые связанные строки, такие как 1 запись в a, 2 записи в b и c, что приводит к двум строкам в результате, потому что внешний ключ связывает много строк в b и c с ONE в a.Декартовое произведение MYSQL вместо связанных строк

enter image description here

Б запрос:

SELECT * 
FROM test.a as tableA 
LEFT OUTER JOIN test.b tableB ON tableB.id_a = tableA.id 
LEFT OUTER JOIN test.c tableC ON tableC.id_a = tableA.id; 

И, наконец, результат запроса: enter image description here

Что я делаю не так, я бы только ожидать результатов, также ограничение внешнего ключа кажется правильным?

Это желаемый результат:

enter image description here

+0

Какой результат вы ожидали? Я имею в виду - как выглядели бы ожидаемые две строки? –

+0

Вы действительно не можете присоединиться к нескольким таблицам, разделяющим «множественное» отношение к одной и той же таблице ... по крайней мере, не без серьезных головных болей и запутанных запросов.Вы можете посмотреть на это как на то, что второе соединение эффективно соединяется с результатами первого объединения. – Uueerdo

+0

вы присоединяетесь к отношениям «один ко многим», поэтому у вас есть частичный декартовой продукт – FuzzyTree

ответ

2

Вы не получаете декартово произведение. Вы получаете именно то, о чем вы просите: результат 2 внешних соединений.

Возможно, вы этого еще не осознали, но вы ожидаете, что 2 соединения объединяются поперечно вместе, чтобы дать вам только 2 записи, магически зная, что идентификатор таблицы B должен отображаться на идентификатор таблицы C. Это фактически возможно который вам понравится, но это намного сложнее, чем вы думаете (см. подсказку в mysql для получения дополнительной информации, но это всего лишь пример того, как это сделать).

Скорее я покажу вам вашу проблему.

  1. Вы просите A внешнего соединения B. Результат 2 записи, потому что кажется, есть 2 записей в таблице В с id_a = 2. Промежуточный подсчет результирующего равен 2.
  2. Вы спрашиваете для Внешнего соединения C. Аналогично, результат равен 2 записям, поскольку, как представляется, в таблице C также есть 2 записи с id_a = 2. Промежуточный результат является 2.

Но вы не просите mysql ничего о том, как организовать/объединить эти 2 промежуточных результирующих набора. Поэтому mysql пересекает их вместе, что, возможно, заставило вас изначально подумать, что это декартовый продукт, и отображает конечный результат, который вы наблюдали. Всего строк = 4, 2 из 1-го результирующего набора, раз 2, из 2-го результирующего набора.

Декартовой продукт включал бы все записи всех трех таблиц, скрещенных друг с другом: раз b раз c.

Итак, в заключение, можно «взломать» запрос, чтобы показать, как вы хотите, путем установления стыковка критериев между С и В. Например:

SELECT * 
FROM test.a as tableA 
LEFT JOIN test.b tableB ON tableB.id_a = tableA.id 
LEFT JOIN test.c tableC ON tableC.id_a = tableA.id AND tableC.id = tableB.id 
; 

Но на самом деле это хак, вы, вероятно, необходимо определить более высокий критерий, чем технический идентификатор идентификатора.

+0

Я также выгляжу как декартова продукт, потому что там это только одна строка в таблице a, и все строки из таблиц b и c связаны с ней. –

+0

Правда, это действительно результат 4 по совпадению в этом случае. – Sebas

+0

На самом деле, он получил бы то же самое с внутренними соединениями. – Uueerdo

Смежные вопросы