Да, но вы можете обнаружить, что вы получаете строки из каждой таблицы, которые повторяются при объединении в уникальную комбинацию.Это называется декартовым произведением
Table A
OrderNr, CustNr
1,C1
1,C2
2,C1
2,C2
TableB
OrderNr,ItemNr
1,i1
1,i2
SELECT * FROM a JOIN b ON a.OrderNr = b.OrderNr
1,C1,1,i1
1,C1,1,i2
1,C2,1,i1
1,C2,1,i2
Это происходит потому, что составные первичные ключи могут содержать повторяющиеся элементы, если комбинация элементов уникальна.Соединение только с одной частью PK, и эта часть является элементом, который повторяется (мой custnr 1 повторяется дважды в каждой таблице, хотя itemnr и CustNr означают, что строки уникальны) приводит к умноженному результату - 2 строки из Acustnr 1, умноженные на 2 строки из B, которые custnr 1, дают в общей сложности 4 строки
Работает ли это и с обычным / натурным соединением?
Обычные объединения (INNER, LEFT OUTER, RIGHT OUTER, FULL OUTER) объединят строки из двух таблиц или подзапросов, когда условие ON выполнено.Предложение в ON похоже на предложение WHERE, да, в том смысле, что оно представляет утверждение, истинное или ложное (предикат).Если утверждение верно, строки объединяются.Вам даже не нужно делать это с данными из таблиц - вы даже можете сказать a JOIN b ON 1=1
, и все строки из A будут объединены с каждой строкой из B. Как уже отмечалось, первичные ключи вообще не участвуют в JOINS,хотя первичные ключи часто полагаются на индексы, и эти индексы могут использоваться для ускорения соединения, но они не являются жизненно важными для него.
Существуют и другие объединения (CROSS, NATURAL ..);соединение CROSS похоже на приведенный выше пример 1 = 1, вы не указываете ON, каждая строка из A соединяется с каждой строкой из B, в соответствии с дизайном.ИМХО - НАТУРАЛЬНОЕ СОЕДИНЕНИЕ, ИМХО - база данных будет искать имена столбцов, которые являются одинаковыми в обеих таблицах, и объединяться в них.Проблема в том, что в будущем вещи могут перестать работать, если кто-то добавит столбец с тем же именем, но разным содержанием / значением в две таблицы.Ни одна серьезная производственная система, с которой я когда-либо сталкивался, не использовала NATURAL join.Вы можете обойтись без некоторого набора текста, если ваши столбцы для объединения названы одинаково, с помощью USING - SELECT * FROM a JOIN b USING (col)
- здесь и A, и B имеют столбец с именем col
.ИСПОЛЬЗОВАНИЕ имеет некоторые преимущества, особенно перед естественным соединением, в том, что оно не разваливается, если другой столбец с тем же именем, что и существующий, но у него тоже есть некоторые недоброжелатели - вы не можете сказать USING(col) AND ...
.Большинство людей просто продолжают писать ON и забывают, что ИСПОЛЬЗОВАНИЕ
NATURAL join также НЕ использует первичные ключи.Не существует стиля соединения (о котором я знаю), который бы смотрел на отношение внешнего ключа между двумя таблицами и использовал его в качестве условия соединения
И тогда верно ли, что если я попытаюсь присоединиться к Первичномуключ и внешний ключ двух таблиц, что он работает как команда "где"?
Трудно понять, что вы подразумеваете под этим, но если вы имеете в виду, что A JOIN B ON A.primarykey = B.primary_key_in_a
, тогда это сработает, конечно.Если вы имеете в виду A CROSS JOIN B WHERE A.primarykey = B.primary_key_in_a
, то это тоже сработает, но я бы определенно избегал этого - никто не пишет SQL таким образом, и общее преимущество состоит в том, чтобы отказаться от использования WHERE для создания условий соединения (вы все еще видите, что люди пишутпо старому стилю FROM a,b WHERE a.col=b.col
, но это также сильно не рекомендуется), и вместо этого включите их в ON
Итак, в итоге:
SELECT * FROM a JOIN b ON a.col1 = b.col2
Объединяет все строки из a со всеми строками изb, где значения в col1 равны значениям в col2.Для работы с этим не требуется никаких первичных ключей