После изучения принципа работы объединения, можно перейти к более детальному обсуждению различных типов объединений, поддерживаемых SQL MySQL. MySQL поддерживает пять типов объединений:
■ полное объединение;
■ внутреннее объединение;
■ внешнее объединение;
■ самообъединение;
■ объединение UNION.
В следующих разделах каждый их этих типов обсуждается детальнее с соответствующими примерами и иллюстрациями.
Полное объединение
Простейшим типом объединения является полное объединение, которое объединяет все задействованные таблицы для создания произведения "включить все". Рассмотрим пример, в котором используются две таблицы с перечислением физических характеристик человека.
В этом случае в результирующем наборе присутствуют столбцы из обеих таблиц, создавая все возможные комбинации. Этот тип объединения называется полным, потому что количество строк объединенной таблицы равно произведению строк таблиц, задействованных в объединении. Это подтверждается предыдущим примером. В таблице attribyte - две строки, а в таблице color - три, поэтому в общей таблице должно быть 2 х 3 = 6 строк.
Вполне очевидно, что полное объединение такого типа может привести к большим проблемам в работе сервера базы данных. В следующем листинге показано, что произойдет, если в это объединение добавить еще две таблицы.
Несмотря на то, что каждая из задействованных в этом объединении таблиц имеет менее 5 записей, окончательный результат объединения содержит 2 х 3 х 2 х 4 = 48 записей. Данный результат нельзя назвать впечатляющим. Но ведь это только 4 таблицы, содержащие в общем итоге 11 записей. А если объединить 4 таблицы по 100 строк в каждой?
Внутреннее объединение
Наиболее часто используется т.н. внутреннее объединение. К тому же этот тип объединения считается и наиболее симметричным, т.к. он предполагает наличие соответствия в каждой таблице, являющейся частью объединения. Несоответствующие строки исключаются из окончательного результирующего набора.
Наиболее распространенным примером внутреннего объединения является объединение по эквивалентности, при котором приравниваются определенные поля из разных таблиц. В этом случае окончательный результирующий набор включает только те строки таблиц, которые совпадают в указанных полях (примером может послужить первый сегмент этой главы, который используется в объединении по эквивалентности).
В качестве примера рассмотрим также следующие таблицы, в которых приводится список проданных продуктов и их количество.
Перегрузка данными
Так как полные объединения создают большие результирующие наборы, рекомендуется к объединению добавлять предложение WHERE для исключения ненужных записей.
Как и в предыдущем примере, для еще большего сужения критериев выборки результирующего набора можно ограничиться только теми товарами, которые продаются в количестве более 2 тыс. штук.
Играть словами
В целях однозначности, MySQL также допускает использование в этих операторах вместо запятой ключевых слов INNER JOIN и CROSS JOIN. Например, оба эти оператора дают полное объединение:
SELECT countryName, stateName FROM country, state;
SELECT countryName, stateName FROM country CROSS JOIN state;
А вот эти операторы в примере внутреннего объединения по равенству:
SELECT countryName, stateName FROM country, state WHERE state.cid = country.id;
SELECT countryName, stateName FROM country INNER JOIN state WHERE state.cid = country.id;
Заметим, что с обоими ключевыми словами или с запятой можно объединить сколь угодно много таблиц. Например, такой оператор SQL вполне допустим: SELECT * FROM country country CROSS JOIN state CROSS JOIN city;
В данном случае в результирующий набор будут включены только те записи из таблицы sales, в которых значение quantity превышает соответствующее значение avg-Sales из таблицы products.
Внешние объединения
Из предыдущего раздела видно, что внутренние объединения являются симметричными. Для того чтобы попасть в результирующий набор, строки должны совпадать во всех задействованных в объединении таблицах. С другой стороны, т.н. внешние объединения являются асимметричными - все строки с одной стороны объединения должны попадать в окончательный результирующий набор независимо от наличия их полного соответствия.
В зависимости от того, какая из сторон объединения сохранится полностью, различают левое и правое внешние объединения. В левом внешнем объединении в окончательном результирующем наборе присутствуют все записи из таблицы, расположенной в левой части предложения WHERE. В правом внешнем объединении в окончательном результирующем наборе появляются все записи, соответствующие таблице, расположенной в предложении WHERE справа.
Для того чтобы лучше понять этот вопрос, рассмотрим следующие три таблицы. В первой из них дается перечень пользователей, во второй - перечень групп, к которым можно отнести пользователей, а в третьей отражена принадлежность пользователей к той или иной группе. Таблица groups может содержать нуль, один и более пользователей. Таблицы groups и users связаны между собой полями uid и gid таблицы users_groups.
Теперь, имея представление о внутренних объединениях, нам очень просто объединить эти три таблицы в один список, отражающий принадлежность каждого пользователя к определенной группе.
Это симметричный список, который не содержит никакой информации о пользователях, не принадлежащих ни к одной из групп, или о группах, вообще не связанных с пользователями.