2013-05-20 4 views
1

У меня есть вопрос относительно Inner Joins в MySQl. Из моего ограниченного понимания MySQL, таблица результатов, созданная внутренним соединением, содержит только строки, которые существовали в обеих таблицах. То есть, например, если таблица 1 содержит строку для Joe и строку для Sally, а таблица2 содержит только строку для Sally, внутреннее объединение будет содержать только одну строку: строку для Sally.MySQL Inner Join Результаты

Например:

В базе данных, которая содержит 2 таблицы,

Таблица 1 (Домашнее животное)

petName petType 
Unicorn Horse 
Pegasus Horse 
Lion Cat 

Таблица 2 (цвет)

petName petColor 
Unicorn white 
Unicorn silver 
Fish Gold 

Используя запрос

SELECT * FROM Pet,Color WHERE Pet.petName = Color.petName 

Почему результат запроса?

petName petType petName petColor 
Unicorn Horse Unicorn white 
Unicorn Horse Unicorn silver 

Почему там «Unicorn лошадь» во втором ряду, когда есть только один «Unicorn Лошадь» в таблице 1? Был бы я прав, говоря, что MySQL соответствует термину «Единорог» в таблице 1 и таблице 2 и перечисляет строки в обеих таблицах, в которых есть слово «Единорог». Однако так как это привело бы к

petName petType petName petColor 
Unicorn Horse Unicorn white 
< NULL > Unicorn silver 

MySQL автоматически заменяет значение с помощью строки «Unicorn Лошадь» в таблице один, так как он соответствует «Unicorn» ключевое слово, используемое в запросе?

Если да, то в чем бы заключалось это, поскольку MySQL только давал мне избыточные данные во второй строке, для которой я не нужен? Кроме того, я был бы в состоянии работать вокруг этого, используя

SELECT * FROM Pet LEFT JOIN Color 
ON Pet.petName=Color.petName 
WHERE Pet.petName="Unicorn"? 

Я наткнулся на этот пример в PHP & MYSQL для чайников и никак не мог получить его. Я был бы признателен, если бы какая-то душа могла это прояснить.

ответ

2

Если выполняется SELECT * from Pet, Color (без пункта WHERE), вы получите следующий ответ:

petName petType petName petColor 
Unicorn Horse Unicorn white 
Pegasus Horse Unicorn white 
Lion Cat  Unicorn white 
Unicorn Horse Unicorn silver 
Pegasus Horse Unicorn silver 
Lion Cat  Unicorn silver 
Unicorn Horse Fish Gold 
Pegasus Horse Fish Gold 
Lion Cat  Fish Gold 

Это называется CROSS JOIN; SQL-сервер будет брать каждую строку из таблицы 1 и сопоставлять ее с каждой строкой в ​​таблице 2.

Когда вы добавляете WHERE Pet.petName = Color.petName, SQL-сервер будет отфильтровывать все строки, где это предложение неверно.Таким образом, так как только petName с определенным petColor является Unicorn, вы остались с

petName petType petName petColor 
Unicorn Horse Unicorn white 
Unicorn Horse Unicorn silver 

Если бы ваш запрос вместо был WHERE Pet.petName != Color.petName, вы бы дополнение или

petName petType petName petColor 
Pegasus Horse Unicorn white 
Lion Cat  Unicorn white 
Pegasus Horse Unicorn silver 
Lion Cat  Unicorn silver 
Unicorn Horse Fish Gold 
Pegasus Horse Fish Gold 
Lion Cat  Fish Gold 

Если вы хотите только в одном ряду от Pet, где указан цвет, вы можете использовать

SELECT * FROM Pet 
    WHERE EXISTS (SELECT * FROM Color where Color.petName = Pet.petName) 

, который вернет

petName petType 
Unicorn Horse 

Этот запрос по существу означает «выбрать все строки из Pet, где есть по крайней мере один Color, определенные для этого домашнего животного, по названию».

Это называется полусоединением, поскольку SQL-сервер может выполнять соединение с Color за кулисами, но данные из Color не возвращаются в результирующий набор. Поскольку нет данных Color, вы получите каждую строку от Pet только один раз, независимо от количества строк Color, определенных для любого заданного petName.

+0

Выполняет SELECT * FROM Pet WHERE EXISTS (SELECT * FROM Color, где Color.petName = Pet.petName) перевести на простой английский, в «выбрать строки (строки) в таблице Pet, где данные в столбце petName соответствуют данным в столбце petName в таблице Цвет "? Я спрашиваю об этом, потому что я все еще не слишком уверен в синтаксисе для MySQL. Благодаря! –

+0

@ Ken-- обновил ответ, чтобы включить объяснение. –

3

Результат такой, как ожидалось. Вы соединяете две таблицы со столбцом PetName на обеих таблицах. Unicorn Horse Из таблицы Pet дважды отображается в результирующем наборе, поскольку она имеет совпадения по двум записям в таблице Color.

Для дальнейшего получить больше знаний о присоединяется, любезно перейдите по ссылке ниже:

1

Где есть «несколько строк на одной стороне на одной строке с другой стороны», то значения одной строки повторяются.

Так что это правильно:

petName petType petName petColor 
Unicorn Horse Unicorn white 
Unicorn Horse Unicorn silver 

SQL не может генерировать это с INNER JOIN.

petName petType petName petColor 
Unicorn Horse Unicorn white 
< NULL > Unicorn silver 

Это так просто.

+0

Извините, что прерывать, но делать правое соединение не дает результата, который вы показали. – Walter

+0

@ Zeus: объясните, пожалуйста, – gbn

+2

здесь: http://sqlfiddle.com/#!2/f564e/2 'единорог' имеет одно совпадение с другой таблицей. – Walter

0

Это как и ожидалось.

Ваш запрос объединяет столбцы petName из каждой таблицы и возвращает результат, в котором он совпадает. Здесь он находит совпадение из таблицы Pet с именем Unicorn Horse в таблице цвета с цветом white, а затем находит второй матч из таблицы Pet с именем Unicorn Horse в таблице цвета с цветом silver

0

Это не значит, что MySQL является заполнение в нулевых данных во второй строке.

Ваш запрос буквально «Дай мне все, что из обеих таблиц, где PetName является лошадь.

Что касается MySQL, то она не знает, что вы хотите, чтобы первый единорог ряд в домашних животных, чтобы быть белым, а затем есть дополнительный единорог, который не соответствует чему-либо серебру. Вместо этого он говорит: «У меня есть этот единорог, который имеет 2 атрибута: белый и серебристый. И, основываясь на моем первом столе, я знаю, что все единороги - лошади. Таким образом, у меня есть единорог с белой лошадью и серебряный единорог ».

Что касается этой цели, то вы можете удалить избыточные данные. Например, если у каждого бизнеса есть 1 адрес, но несколько продавцов, вы не хотите чтобы сохранить тот же адрес у каждого продавца, потому что тогда, когда пришло время внести изменения, вам необходимо обновить множество записей.

Вместо этого вы можете сказать: «Testco находится на главной улице 123. Боб, Джон, Салли и Фрэнк - все продавцы в Testco ». Тогда ответ на вопрос« Что такое адрес Боба »просто« 123 Main Street ». Но вы посмотрите на запись Testco, чтобы получить это, а не в записи Боба .

0

у вас есть один единорог домашнего животного, которое приходит в двух цветах, так что две строки. Если вы добавили еще одну строки Pet с petname из единорога и типа мифических существ, вы получили бы четыре.

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