SQL加入三个表,加入优先级

vul*_*ino 23 sql

我有三张桌子:R,S和P.

表R通过外键与S连接; 有应该是S中至少一个的记录,所以我可以加入:

SELECT
        *
    FROM 
        R
    JOIN    S ON (S.id = R.fks)
Run Code Online (Sandbox Code Playgroud)

如果在S中没有记录,那么我没有行,这没关系.

然后表S与P连接,其中记录是P可能存在也可能不存在并且与S连接.

所以我这样做

SELECT
        *
    FROM 
        R
    JOIN    S ON (S.id = R.fks)
    LEFT JOIN P ON (P.id = S.fkp)
Run Code Online (Sandbox Code Playgroud)

如果我想将第二个JOIN绑定到S而不是R,如果我可以使用括号,该怎么办?

SELECT
        *
    FROM 
        R
    JOIN    (S ON (S.id = R.fks) JOIN P ON (P.id = S.fkp))
Run Code Online (Sandbox Code Playgroud)

或者这是R,S和P之间笛卡尔积的自然行为?

rak*_*ice 37

所有类型的外连接和普通连接都在相同的优先级类中,并且运算符在查询的给定嵌套级别从左到右生效.您可以将连接表达式放在括号中的右侧,以使其首先生效; 只记得你必须移动ON现在在你加入parens的连接之外的连接的子句.

(PostgreSQL示例)

SELECT * FROM a LEFT JOIN b ON (a.id = b.id) JOIN c ON (b.ref = c.id);

ab join首先生效,但是我们可以通过将它放在括号中来强制bc join首先生效,如下所示:

SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);

通常,您可以通过移动连接并更改外连接方向来表达相同的内容而无需额外的括号,例如

SELECT * FROM b JOIN c ON (b.ref = c.id) RIGHT JOIN a ON (a.id = b.id);

  • 需要说明的是:所有联接运算符都具有相同的优先级,并且都具有从左到右的关联性。这是减法(-)和除法(/)运算符在几乎所有编程语言中的工作方式。更改操作数的顺序对其“优先级”(SQL语法的一个方面,无论如何都不改变操作数)没有影响。这样做利用了连接的从左到右的关联性,以实现复合连接的期望语义。但是它既不会改变表达式中任何东西的优先顺序,也不会改变它的关联性,只会改变其解释的上下文。 (3认同)
  • 如果您正在寻找比优先级或关联性更不具体的术语,我建议您使用“绑定”。这种用法既不太具体,也更非正式。运算符和操作数的绑定受运算符优先级和运算符结合性的影响。无论如何,应该认识到优先级和结合性是相关但非常不同的概念。 (2认同)
  • 回复:改写。我建议对齿轮进行润滑以防止磨削。当准确性和清晰度非常容易获得时,没有理由重复NO来选择模糊性和歧义性。在技​​术讨论中,您将定义明确,易于理解,得到广泛认可且相关的术语称为“术语”,这至少表明您对该主题的态度不那么认真。运算符优先级根本不处理操作数顺序,只有运算符关联性可以。至于后来起源于数学的术语,优先级也是如此。 (2认同)