OUTER JOIN
适用于 ✅ 开源版 ✅ 专业版 ✅ 企业版
当 INNER JOIN 不匹配时,OUTER JOIN
允许生成一些额外的行。有 3 种类型的 OUTER JOIN
-
LEFT JOIN
或LEFT OUTER JOIN
: 始终生成连接左侧的所有行,以及连接右侧的仅匹配行 -
RIGHT JOIN
或RIGHT OUTER JOIN
: 始终生成连接右侧的所有行,以及连接左侧的仅匹配行 -
FULL JOIN
或FULL OUTER JOIN
: 始终生成连接左侧和右侧的所有行
关键字 OUTER
在 SQL 和 jOOQ 中都是可选的,并且根本不影响查询语义。
最好用例子来解释这一点。
LEFT JOIN
LEFT JOIN
是 OUTER JOIN
类型中最流行的一种。
以下查询生成所有作者,以及可能的他们的书籍
SELECT AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, BOOK.TITLE FROM AUTHOR LEFT JOIN BOOK ON BOOK.AUTHOR_ID = AUTHOR.ID
create.select( AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, BOOK.TITLE) .from(AUTHOR) .leftJoin(BOOK).on(BOOK.AUTHOR_ID.eq(AUTHOR.ID)) .fetch();
结果可能如下所示
+------------+-----------+--------------+ | FIRST_NAME | LAST_NAME | TITLE | +------------+-----------+--------------+ | George | Orwell | 1984 | | George | Orwell | Animal Farm | | Paulo | Coelho | O Alquimista | | Paulo | Coelho | Brida | <-- Above rows are also produced by INNER JOIN | Jane | Austen | | <-- This row is only produced by LEFT JOIN or FULL JOIN +------------+-----------+--------------+
可以看出,生成了连接左侧(作者)的所有行,包括在连接右侧(书籍)上没有任何匹配项的行。我们还没有 Jane Austen 的任何书籍,但 Jane Austen 在结果集中。如果这是一个 INNER JOIN,她就不会在结果集中。
RIGHT JOIN
RIGHT JOIN
只是 LEFT JOIN
的逆运算,几乎从未使用过。
以下查询生成所有书籍,以及可能的他们的作者
SELECT AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, BOOK.TITLE FROM AUTHOR RIGHT JOIN BOOK ON BOOK.AUTHOR_ID = AUTHOR.ID
create.select( AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, BOOK.TITLE) .from(AUTHOR) .rightJoin(BOOK).on(BOOK.AUTHOR_ID.eq(AUTHOR.ID)) .fetch();
结果可能如下所示
+------------+-----------+--------------------+ | FIRST_NAME | LAST_NAME | TITLE | +------------+-----------+--------------------+ | George | Orwell | 1984 | | George | Orwell | Animal Farm | | Paulo | Coelho | O Alquimista | | Paulo | Coelho | Brida | <-- Above rows are also produced by INNER JOIN | | | The Arabian Nights | <-- This row is only produced by RIGHT JOIN or FULL JOIN +------------+-----------+--------------------+
可以看出,生成了连接右侧(书籍)的所有行,包括在连接左侧没有任何匹配项的行。《一千零一夜》没有特定的作者,但它仍然在结果集中。如果这是一个 INNER JOIN,它就不会在结果集中。
请注意,RIGHT JOIN
只是一个反转的 LEFT JOIN
,您更有可能这样编写相同的查询,而没有语义上的差异
SELECT AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, BOOK.TITLE FROM BOOK LEFT JOIN AUTHOR ON BOOK.AUTHOR_ID = AUTHOR.ID
create.select( AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, BOOK.TITLE) .from(BOOK) .leftJoin(AUTHOR).on(BOOK.AUTHOR_ID.eq(AUTHOR.ID)) .fetch();
存在复杂的连接树,其中 RIGHT JOIN
可能会使事情变得更简单,但在大多数情况下,它只会使查询的可读性和可维护性复杂化。
FULL JOIN
当不应省略任何一个表中的行时,FULL JOIN
是一种偶尔有用的连接两个表的方式。例如,这对于比较两个数据集可能很有用。
以下查询生成所有作者和所有书籍
SELECT AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, BOOK.TITLE FROM AUTHOR FULL JOIN BOOK ON BOOK.AUTHOR_ID = AUTHOR.ID
create.select( AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, BOOK.TITLE) .from(AUTHOR) .fullJoin(BOOK).on(BOOK.AUTHOR_ID.eq(AUTHOR.ID)) .fetch();
结果可能如下所示
+------------+-----------+--------------------+ | FIRST_NAME | LAST_NAME | TITLE | +------------+-----------+--------------------+ | George | Orwell | 1984 | | George | Orwell | Animal Farm | | Paulo | Coelho | O Alquimista | | Paulo | Coelho | Brida | <-- Above rows are also produced by INNER JOIN | Jane | Austen | | <-- This row is only produced by LEFT JOIN or FULL JOIN | | | The Arabian Nights | <-- This row is only produced by RIGHT JOIN or FULL JOIN +------------+-----------+--------------------+
select(BOOK.ID, AUTHOR.ID).from(BOOK.leftJoin(AUTHOR).on(BOOK.AUTHOR_ID.eq(AUTHOR.ID)))
翻译成以下特定方言的表达式
所有方言
SELECT BOOK.ID, AUTHOR.ID FROM BOOK LEFT OUTER JOIN AUTHOR ON BOOK.AUTHOR_ID = AUTHOR.ID
使用 jOOQ 3.21 生成。早期 jOOQ 版本的支持可能有所不同。 在我们的网站上翻译您自己的 SQL
反馈
您对此页面有任何反馈吗?我们很乐意听到!