LEFT OUTER JOIN 中的最大行数是多少?

What is the maximum # of rows in a LEFT OUTER JOIN?

对于给定的任意两个 tables,假设 table 1 有 i 行,table 2 有 j 行,有人可以向我解释一下吗如果 table 1 是 "left" table,我们怎么可能在 LEFT OUTER JOIN 中得到总共 i * j 行?我一直认为 LEFT OUTER JOIN 总是 return 左边的总行数 table ?

A left join returns 中第一个 table 中的所有行。对于每一行,它 returns 第二个 table 中符合 on 条件的所有行。如果没有行匹配 on 条件,则仍返回第一个 table 的行,并删除其他列 NULL

因此,如果您想要 i * j 行,只需执行:

from t1 left join
     t2
     on 1 = 1

在内部联接中,对于 "left" table 中的每一行,输出中的行数将与 中匹配的 行一样多"right" table(在连接条件上匹配,即);这可以是 0j 之间的任何值。因此,内部联接可以 return 在 0i*j 行之间的任何位置。顺便说一下,两者都是可能的;只需考虑连接条件 null is not null(获得 0 行)或 null is null(获得笛卡尔连接)。

outer 联接(特别是左外部联接)的唯一区别是 "left" table 的每一行都将位于输出中至少有一行 - 即使右边没有匹配的行 table。这就是外连接 的真正含义 。所以唯一的区别是在左外连接中,输出将在 ii*j 行之间,并且两者都是可能的(与上面相同的连接条件)。

关于您关于获取最大行数的问题 - 对于更多的 "natural" 示例,假设两个 table 都有一列 purchase_date,并且由于某种原因所有行在两个 table 中,该列中的日期完全相同(非空)。然后,如果您在 left_table.purchase_date = right_table.purchase_date 上加入,您将获得笛卡尔连接,其中有 i*j 行。

总行数可以是 i * j,也可以小于 i * j,具体取决于连接条件和数据。这里有2个例子。

CREATE TABLE t1(
   id   VARCHAR(1)
);

INSERT INTO t1(id) VALUES ('a');
INSERT INTO t1(id) VALUES ('b');
INSERT INTO t1(id) VALUES ('c');
INSERT INTO t1(id) VALUES ('d');

CREATE TABLE t2(
   id       VARCHAR(1)
  ,col2 INTEGER
);

INSERT INTO t2(id,col2) VALUES ('a',1);
INSERT INTO t2(id,col2) VALUES ('a',2);
INSERT INTO t2(id,col2) VALUES ('a',3);
INSERT INTO t2(id,col2) VALUES ('a',4);
INSERT INTO t2(id,col2) VALUES ('d',1);

以下查询产生计数 20,相当于 cross join,但这是偶然的 由于不精确的连接条件

select 'query 1', count(*) rows
from t1
left join t2 on t2.col2 > 0
;

t2 中的所有行的 col2 > 0,因此 t1 的每一行都乘以 t2 中的每一行(4 t1 行 * 5 t2 行 = 合并结果中的 20 行)。

以下查询产生的计数为 7,小于 i * j,因为 连接条件是精确的

select 'query 2', count(*) rows
from t1
left join t2 on t1.id = t2.id and t2.col2 > 0
;
  1. t1 中的 'a' 与 t2 中的 'a' 匹配(4 行)
  2. 'b','c' 在 t1 中不匹配(2 行)
  3. 'd' 匹配但仅匹配 t2 中的 1 行(1 行)
  4. 所以,总共 4 + 2 + 1 = 7 行