Автор оригинала: Vlad Mihalcea.
Вступление
В этой статье мы рассмотрим, как предложение JOIN USING работает в SQL и как мы можем использовать его для замены предложения ON condition, когда столбцы, используемые для соединения двух таблиц, имеют одинаковые имена как в родительской, так и в дочерней таблицах.
Таблицы базы данных
Чтобы продемонстрировать, как работает предложение JOIN USING, мы собираемся использовать следующие таблицы post
и post_comment
базы данных, которые образуют связь один ко многим таблицам через post_id
Столбец внешнего ключа в post_comment
таблице, которая ссылается на post_id
столбец первичного ключа в post
таблице:
В родительской таблице post
есть следующие 3 строки:
| post_id | title | |---------|-----------| | 1 | Java | | 2 | Hibernate | | 3 | JPA |
и в таблице post_comment
дочерняя таблица содержит следующие 3 записи:
| post_comment_id | review | post_id | |-----------------|-----------|---------| | 1 | Good | 1 | | 2 | Excellent | 1 | | 3 | Awesome | 2 |
Предложение SQL JOIN ON с пользовательской проекцией
Как правило, при написании запроса на ВНУТРЕННЕЕ СОЕДИНЕНИЕ или ЛЕВОЕ СОЕДИНЕНИЕ мы используем предложение ON для определения условия соединения.
Например, чтобы получить комментарии, а также соответствующий заголовок и идентификатор записи, мы можем написать следующий запрос на проекцию SQL:
SELECT post.post_id, title, review FROM post INNER JOIN post_comment ON post.post_id = post_comment.post_id ORDER BY post.post_id, post_comment_id
И мы получим следующий набор результатов:
| post_id | title | review | |---------|-----------|-----------| | 1 | Java | Good | | 1 | Java | Excellent | | 2 | Hibernate | Awesome |
Предложение SQL JOIN USING с пользовательской проекцией
Если столбец внешнего ключа и столбец, на который он ссылается, имеют одно и то же имя, вы можете использовать предложение USING, например:
SELECT post_id, title, review FROM post INNER JOIN post_comment USING(post_id) ORDER BY post_id, post_comment_id
И результирующий набор приведенного выше запроса будет идентичен предыдущему SQL-запросу, в котором использовалось предложение ON:
| post_id | title | review | |---------|-----------|-----------| | 1 | Java | Good | | 1 | Java | Excellent | | 2 | Hibernate | Awesome |
Предложение USING работает для Oracle, PostgreSQL, MySQL и MariaDB. SQL Server не поддерживает предложение USING, поэтому вместо него необходимо использовать предложение ON.
Предложение USING можно использовать с инструкциями INNER, LEFT, RIGHT и FULL JOIN.
Предложение SQL JOIN ON с SELECT *
Теперь, если мы изменим предыдущий запрос предложения ON, чтобы выбрать все столбцы:
SELECT * FROM post INNER JOIN post_comment ON post.post_id = post_comment.post_id ORDER BY post.post_id, post_comment_id
Мы собираемся получить следующий набор результатов:
| post_id | title | post_comment_id | review | post_id | |---------|-----------|-----------------|-----------|---------| | 1 | Java | 1 | Good | 1 | | 1 | Java | 2 | Excellent | 1 | | 2 | Hibernate | 3 | Awesome | 2 |
Обратите внимание, что post_id
дублируется, поскольку таблицы post
и post_comment
содержат столбец post_id|/.
Предложение SQL JOIN USING с SELECT *
С другой стороны, если мы запустим запрос SELECT*, содержащий предложение USING:
SELECT * FROM post INNER JOIN post_comment USING(post_id) ORDER BY post_id, post_comment_id
Мы собираемся получить следующий набор результатов:
| post_id | title | post_comment_id | review | |---------|-----------|-----------------|-----------| | 1 | Java | 1 | Good | | 1 | Java | 2 | Excellent | | 2 | Hibernate | 3 | Awesome |
Мы видим, что столбец post_id
дедуплицирован, поэтому в результирующий набор включается один столбец post_id
.
Вывод
Если вы создадите схему базы данных таким образом, чтобы имена столбцов внешнего ключа соответствовали столбцам, на которые они ссылаются, а условия СОЕДИНЕНИЯ проверяют только, равно ли значение столбца внешнего ключа значению его зеркального столбца в другой таблице, вы можете использовать предложение USING.
В противном случае, если имя столбца внешнего ключа отличается от столбца, на который он ссылается, или вы хотите включить более сложное условие соединения, вместо этого следует использовать предложение ON.