В любой реальной реляционной базе данных вся информация разбита на отдельные таблицы. Между многими таблицами установлены взаимосвязи, зафиксированные в схеме. Однако с помощью запросов Sql можно создать соединение между данными, которые не включены в схему. Это делается путем выполнения операции соединения, которая позволяет создавать отношения между любым количеством таблиц и объединять даже кажущиеся несопоставимыми данные.
В этой статье особое внимание будет уделено левому внешнему соединению. Прежде чем мы начнем описывать этот тип подключения, давайте добавим несколько таблиц в базу данных.
Подготовка необходимых таблиц
Предположим, наша база данных содержит информацию о людях и их недвижимости. Основная информация основана на трех таблицах: Peoples (люди), Realty (недвижимость), Realty_peoples (таблица с отношениями, кому из людей какая собственность принадлежит). Предположим, в таблицах хранятся следующие данные о людях:
Народы |
||||
я бы |
L_name |
F_name |
Отчество |
День рождения |
1 |
Иванова |
Дарья |
Борисовна |
16 июля 2000 г |
2 |
Пугин |
Владислав |
Николаевич |
29.01.1986 |
3 |
Евгенино |
Александр |
Федорович |
30.04.1964 |
4 |
Аннина |
Любовь |
Павловна |
31.12.1989 |
5 |
Герасимовская |
Надеяться |
Павловна |
14.03.1992 |
6 |
Герасимовский |
Олег |
Альбертович |
29.01.1985 |
7 |
Сухановский |
Юрий |
Андреевич |
25.09.1976 |
восемь |
Сухановская |
Юлия |
Юрьевна |
01.10.2001 |
По недвижимости:
Недвижимость |
|
я бы |
адрес улицы |
1 |
архангела, ул. Воронина, 7, квартира 6 |
2 |
архангела, ул. Северодвинская, 84, кв. 9, комн. 5 |
3 |
Архангельская область, г. Северодвинск, ул. Ленина, д. 134, кв. 85 |
4 |
Архангельская область, г. Новодвинск, ул. Пролетарская, 16, кв. 137 |
5 |
архангела, пл. Теречина, д. 89, кв. 13 |
По отношениям между людьми и недвижимостью:
Realty_peoples |
||
people_id |
id_realty |
тип |
7 |
3 |
Совместное владение |
восемь |
3 |
Совместное владение |
3 |
5 |
Собственный |
7 |
1 |
Собственный |
5 |
4 |
Совместная собственность |
6 |
4 |
Совместная собственность |
Left join (Sql) – описание
Левое соединение имеет следующий синтаксис:
Table_A LEFT JOIN table_B [{предикат ON} | {USING column_list}] |
А схематично это выглядит так:
И это выражение переводится как «Выбрать все строки без исключения из таблицы A, а таблица B выводит только строки, соответствующие предикату. Если нет пар для строк таблицы A в таблице B, заполните полученные столбцы значениями Null».
Чаще всего при выполнении левого соединения указывается ON, USING используется только тогда, когда имена столбцов, которые нужно объединить, совпадают.
Left join — примеры использования
С помощью левого соединения мы можем увидеть, есть ли у всех людей в Peoples недвижимость. Для этого запустите следующий пример запроса в левом соединении sql:
ВЫБЕРИТЕ Peoples. *, Realty_peoples.id_realty, Realty_peoples.type DA Peoples LEFT ПРИСОЕДИНИТЬСЯ Realty_peoples ON Peoples.id = Realty_peoples.id_peoples; |
И получаем следующий результат:
Запрос 1 |
||||||
я бы |
L_name |
F_name |
Отчество |
День рождения |
id_realty |
тип |
1 |
Иванова |
Дарья |
Борисовна |
16 июля 2000 г |
||
2 |
Пугин |
Владислав |
Николаевич |
29.01.1986 |
||
3 |
Евгенино |
Александр |
Федорович |
30.04.1964 |
5 |
Собственный |
4 |
Аннина |
Любовь |
Павловна |
31.12.1989 |
||
5 |
Герасимовская |
Надеяться |
Павловна |
14.03.1992 |
4 |
Совместная собственность |
6 |
Герасимовский |
Олег |
Альбертович |
29.01.1985 |
4 |
Совместная собственность |
7 |
Сухановский |
Юрий |
Андреевич |
25.09.1976 |
1 |
Собственный |
7 |
Сухановский |
Юрий |
Андреевич |
25.09.1976 |
3 |
Совместное владение |
восемь |
Сухановская |
Юлия |
Юрьевна |
01.10.2001 |
3 |
Совместное владение |
Как видите, Иванова Дарья, Пугин Владислав и Аннина Любовь не имеют зарегистрированных прав на недвижимость.
Что мы получим, используя внутреннее соединение? Как вы знаете, он исключает несовпадающие строки, поэтому три человека из нашей последней выборки просто выпадут:
Запрос 1 |
||||||
я бы |
L_name |
F_name |
Отчество |
День рождения |
id_realty |
тип |
3 |
Евгенино |
Александр |
Федорович |
30.04.1964 |
5 |
Собственный |
5 |
Герасимовская |
Надеяться |
Павловна |
14.03.1992 |
4 |
Совместная собственность |
6 |
Герасимовский |
Олег |
Альбертович |
29.01.1985 |
4 |
Совместная собственность |
7 |
Сухановский |
Юрий |
Андреевич |
25.09.1976 |
1 |
Собственный |
7 |
Сухановский |
Юрий |
Андреевич |
25.09.1976 |
3 |
Совместное владение |
восемь |
Сухановская |
Юлия |
Юрьевна |
01.10.2001 |
3 |
Совместное владение |
Казалось бы, второй вариант тоже удовлетворяет условиям нашей задачи. Однако, если мы будем добавлять все больше и больше таблиц, три человека из результата уже безвозвратно исчезнут. Поэтому на практике при объединении нескольких таблиц левое и правое объединение гораздо более распространено, чем внутреннее объединение.
Давайте продолжим рассматривать примеры с левым соединением sql. Добавим таблицу с адресами наших объектов недвижимости:
ВЫБЕРИТЕ Peoples. *, Realty_peoples.id_realty, Realty_peoples.type, Realty.address ОТ НАРОДОВ ВЛЕВО ПРИСОЕДИНЯЙТЕСЬ к Realty_peoples НА Peoples.id = Realty_peoples.id_peoples ВЛЕВО ПРИСОЕДИНЯЙТЕСЬ к Realty ON Realty.id = Realty_peoples.id_realty |
Теперь мы получим не только вид закона, но и адреса объектов недвижимости:
Запрос 1 |
|||||||
я бы |
L_name |
F_name |
Отчество |
День рождения |
id_realty |
тип |
адрес улицы |
1 |
Иванова |
Дарья |
Борисовна |
16 июля 2000 г |
|||
2 |
Пугин |
Владислав |
Николаевич |
29.01.1986 |
|||
3 |
Евгенино |
Александр |
Федорович |
30.04.1964 |
5 |
Собственный |
архангела, пл. Теречина, д. 89, кв. 13 |
4 |
Аннина |
Любовь |
Павловна |
31.12.1989 |
|||
5 |
Герасимовская |
Надеяться |
Павловна |
14.03.1992 |
4 |
Совместная собственность |
Архангельская область, г. Новодвинск, ул. Пролетарская, 16, кв. 137 |
6 |
Герасимовский |
Олег |
Альбертович |
29.01.1985 |
4 |
Совместная собственность |
Архангельская область, г. Новодвинск, ул. Пролетарская, 16, кв. 137 |
7 |
Сухановский |
Юрий |
Андреевич |
25.09.1976 |
3 |
Совместное владение |
Архангельская область, г. Северодвинск, ул. Ленина, д. 134, кв. 85 |
7 |
Сухановский |
Юрий |
Андреевич |
25.09.1976 |
1 |
Собственный |
архангела, ул. Воронина, 7, квартира 6 |
восемь |
Сухановская |
Юлия |
Юрьевна |
01.10.2001 |
3 |
Совместное владение |
Архангельская область, г. Северодвинск, ул. Ленина, д. 134, кв. 85 |
Left join — типичные ошибки использования: неверный порядок таблиц
При соединении таблиц с левым внешним соединением совершаются две основные ошибки:
- Неправильный порядок таблиц, из-за чего данные были потеряны.
- Ошибки при использовании Where в запросе с объединенными таблицами.
Рассмотрим первую ошибку. Прежде чем решать какие-либо проблемы, стоит четко понимать, чего именно мы хотим добиться в итоге. В рассмотренном выше примере мы выделили каждого человека, но мы полностью потеряли информацию об объекте под номером 2, у которого не было владельца.
Если бы мы переставили таблицы в запросе местами и начали с «… From Realty left join Peoples…», то мы бы не потеряли ни одного свойства, чего нельзя сказать о людях.
Однако не стоит, опасаясь левого соединения, переключаться на полное внешнее соединение, которое в результате будет включать как совпадающие, так и несовпадающие строки.
В конце концов, размер выборки часто бывает очень большим, а дополнительные данные действительно бесполезны. Главное — понять, чего вы хотите достичь в итоге: всех людей со списком имеющейся у них собственности или списком всех свойств с их владельцами (если есть).
Left join — типичные ошибки использования: правильность запроса при задании условий в Where
Вторая ошибка также связана с потерей данных и не всегда очевидна.
Вернемся к запросу, когда мы получили данные обо всех людях и их недвижимости, используя левое соединение. Рассмотрим следующий пример с использованием левого соединения sql:
DA Peoples LEFT ПРИСОЕДИНИТЬСЯ Realty_peoples ON Peoples.id = Realty_peoples.id_peoples; |
Предположим, мы хотим уточнить запрос, а не отображать данные, где тип разрешения — «Свойство». Если мы просто добавим, применяя left join sql, пример со следующим условием:
…
Где набрать <> «Свойства» |
тогда мы потеряем данные о людях, у которых нет недвижимости, потому что пустое нулевое значение не сравнивается следующим образом:
Запрос 1 |
||||||
я бы |
L_name |
F_name |
Отчество |
День рождения |
id_realty |
тип |
5 |
Герасимовская |
Надеяться |
Павловна |
14.03.1992 |
4 |
Совместная собственность |
6 |
Герасимовский |
Олег |
Альбертович |
29.01.1985 |
4 |
Совместная собственность |
7 |
Сухановский |
Юрий |
Андреевич |
25.09.1976 |
3 |
Совместное владение |
восемь |
Сухановская |
Юлия |
Юрьевна |
01.10.2001 |
3 |
Совместное владение |
Чтобы предотвратить возникновение ошибок по этой причине, лучше всего установить условие выбора сразу после присоединения. Предлагаем рассмотреть следующий пример с левым соединением sql.
ВЫБЕРИТЕ Peoples. *, Realty_peoples.id_realty, Realty_peoples.type ОТ НАРОДОВ ВЛЕВО ПРИСОЕДИНЯЙТЕСЬ к Realty_peoples (Peoples.id = Realty_peoples.id_peoples И введите <> «Свойства») |
Результат будет следующий:
Запрос 1 |
||||||
я бы |
L_name |
F_name |
Отчество |
День рождения |
id_realty |
тип |
1 |
Иванова |
Дарья |
Борисовна |
16 июля 2000 г |
||
2 |
Пугин |
Владислав |
Николаевич |
29.01.1986 |
||
3 |
Евгенино |
Александр |
Федорович |
30.04.1964 |
||
4 |
Аннина |
Любовь |
Павловна |
31.12.1989 |
||
5 |
Герасимовская |
Надеяться |
Павловна |
14.03.1992 |
4 |
Совместная собственность |
6 |
Герасимовский |
Олег |
Альбертович |
29.01.1985 |
4 |
Совместная собственность |
7 |
Сухановский |
Юрий |
Андреевич |
25.09.1976 |
3 |
Совместное владение |
восемь |
Сухановская |
Юлия |
Юрьевна |
01.10.2001 |
3 |
Совместное владение |
Таким образом, запустив простой пример с левым соединением sql, мы получили список всех людей, также показывающий, у кого из них есть собственность в общей / совместной собственности.
В заключение хочу еще раз подчеркнуть, что к выбору любой информации из базы данных нужно относиться ответственно. Простой пример открыл нам множество нюансов с использованием left join sql, объяснение которому одно: прежде чем приступить к составлению даже элементарного запроса, необходимо тщательно понять, чего именно мы хотим добиться в итоге. Удачи!