我是在使用Postgres数据库的情况下提出这个问题的,尽管我可以想象它将适用于大多数SQL数据库。
在静态类型应用程序中处理数据库查询的结果时,我们需要知道某个特定列是否可以返回null。当基础数据存储在带有NOT NULL约束的表列中时,我们可以自信地在应用程序中将数据键入为非空数据。同样,如果没有约束,那么我们将该列键入为空,因为它可以返回null。
这是足够简单的理由,但事情变得更加复杂,当我们引入左和右联接。例如,如果我们有一个类似于
FROM a
LEFT JOIN b ON a.x = b.y然后,b上的所有列都可以为空,因为结果可能包括没有匹配的b行的a行。同样的,如果我们这样做
FROM a
RIGHT JOIN b ON a.x = b.y现在,a上的所有列都是空的。
在这个意义上,我们可以说某些联接(特别是左和右外部联接)将一种“空性修饰符”应用于查询投影中使用的一组或多个表。
当有多个连接时,我很难理解这种行为是如何工作的。例如:
FROM a
LEFT JOIN b ON a.x = b.y
LEFT JOIN c ON b.x = c.y或
FROM a
LEFT JOIN b ON a.x = b.y
RIGHT JOIN c ON b.x = c.y或
FROM a
LEFT JOIN b ON a.x = b.y
INNER JOIN c ON b.x = c.y
RIGHT JOIN c ON c.x = d.y或
FROM a
LEFT JOIN (b INNER JOIN c ON b.x = c.y) ON a.x = b.y如果我在联接集合上迭代,是否有一组启发式方法可以让我为每个引用的表精确地设置“空修饰符”,以便为查询的结果导出精确的应用程序类型?上面的片段有助于说明这一问题的复杂性,但其思想是有一组启发式方法,可以应用于任意一组联接,而不管其长度、顺序或组合如何。
发布于 2023-05-17 12:51:49
基于一些实验和我对联接顺序在Postgres中的工作方式的理解,我认为可以应用以下规则:
注意:在下面的图表中,
!表示不可空,∅表示可空,单个字母表示表,-X-表示联接,其中X是联接的类型。
FROM子句包含多个源表,则为了本练习的目的,可以将每个附加表转换为交叉连接。FROM子句中的初始源表不可为空。A
!A -L- B
! ∅A现在是可空的。不管连接表之间的依赖关系如何,这都是正确的。A -L- B -R- C
∅ ∅ !A -L- B -R- C -F- D
∅ ∅ ∅ ∅A -L- B -R- C -F- D -C- E
∅ ∅ ∅ ∅ !例如,我们可以有两个连接到A。它们以单独的行形式显示,但它们存在于同一个查询中:
A -L- B
! ∅
A -L- C
! ∅如果我们向A添加了内部联接,则左侧联接不受影响。
A -L- B
! ∅
A -L- C
! ∅
A -I- D
! !但是,如果我们将D加入到另外两个表中的一个,则会影响表的空性:
A -L- B
! ∅
A -L- C -I- D
! ! !在A (源表)和D (内连接表)之间的“链”中的任何附加表也是如此。
https://dba.stackexchange.com/questions/327133
复制相似问题