Главная → Уроки SQL → Урок 6. Объединение таблиц (внутреннее объединение)
SQL - Урок 6. Объединение таблиц (внутреннее объединение)
Предположим, мы хотим узнать, какие темы, и какими авторами были созданы. Для этого проще всего обратиться к таблице Темы (topics):
Но, что если нам необходимо, чтобы в ответе на запрос были не идентификаторы авторов, а их имена? Вложенные запросы нам не помогут,
т.к. в конечном итоге они выдают данные из одной таблицы. А нам надо получить данные из двух таблиц (Темы и Пользователи) и
объединить их в одну. Запросы, которые позволяют это сделать, в SQL называются Объединениями.
Синтаксис самого простого объединения следующий:
SELECT имена_столбцов_таблицы_1, имена_столбцов_таблицы_2 FROM имя_таблицы_1, имя_таблицы_2;
Давайте создадим простое объединение:
Получилось не совсем то, что мы ожидали. Такое объединение научно называется декартовым произведением, когда каждой строке первой
таблицы ставится в соответствие каждая строка второй таблицы. Возможно, бывают случаи, когда такое объединение полезно, но это
явно не наш случай.
Чтобы результирующая таблица выглядела так, как мы хотели, необходимо указать условие объединения. Мы связываем наши таблицы по
идентификатору автора, это и будет нашим условием. Т.е. мы укажем в запросе, что необходимо выводить только те строки, в которых
значения поля id_author таблицы topics совпадают со значениями поля id_user таблицы users:
На схеме будет понятнее:
Т.е. мы в запросе сделали следующее условие: если в обеих таблицах есть одинаковые идентификаторы, то строки с этим идентификатором
необходимо объединить в одну результирующую строку.
Обратите внимание на две вещи:
Если в одной из объединяемых таблиц есть строка с идентификатором, которого нет в другой объединяемой таблице, то
в результирующей таблице строки с таким идентификатором не будет. В нашем примере есть пользователь Oleg (id=5), но он
не создавал тем, поэтому в результате запроса его нет.
При указании условия название столбца пишется после названия таблицы, в которой этот столбец находится (через точку).
Это сделано во избежание путаницы, ведь столбцы в разных таблицах могут иметь одинаковые названия, и MySQL может не понять,
о каких конкретно столбцах идет речь.
Вообще, корректный синтаксис объединения с условием выглядит так:
SELECT имя_таблицы_1.имя_столбца1_таблицы_1,
имя_таблицы_1.имя_столбца2_таблицы_1,
имя_таблицы_2.имя_столбца1_таблицы_2,
имя_таблицы_2.имя_столбца2_таблицы_2
FROM
имя_таблицы_1, имя_таблицы_2
WHERE
имя_таблицы_1.имя_столбца_по_которому_объединяем =
имя_таблицы_2.имя_столбца_по_которому_объединяем;
Если имя столбца уникально, то название таблицы можно опустить (как мы делали в примере), но делать это не рекомендуется.
Как вы понимаете, объединения дают возможность выбирать любую информацию из любых таблиц, причем объединяемых таблиц может быть и
три, и четыре, да и условие для объединения может быть не одно.
Для примера давайте создадим запрос, который покажет нам все
сообщения, к каким темам они относятся и авторов этих сообщений. Конечно, вся эта информация хранится в таблице Сообщения (posts):
Но чтобы вместо идентификаторов отображались имена и названия, нам придется сделать объединение трех таблиц:
Т.е. мы объединили таблицы Сообщения и Пользователи условием posts.id_author=users.id_user, а таблицы Сообщения и Темы -
условием posts.id_topic=topics.id_topic
Объединения, которые мы сегодня рассматривали, называются Внутренними объединениями. Такие объединения
связывают строки одной таблицы со строками другой таблицы (а может еще и третьей таблицы). Но бывают ситуации, когда необходимо,
чтобы в результат были включены строки, не имеющие связанных. Например, когда мы создавали запрос, какие темы и какими авторами
были созданы, пользователь Oleg в результирующую таблицу не попал, т.к. тем не создавал, а потому и связанной строки в объединяемой
таблице не имел.
Поэтому, если нам потребуется составить несколько иной запрос - вывести всех пользователей и темы, которые они создавали,
если таковые имеются - то нам придется воспользоваться Внешним объединением, позволяющим выводить все строки
одной таблицы и имеющиеся связанные с ними строки из другой таблицы. О таких объединениях мы и будем говорить в следующем уроке.