我有两个版本的多重连接,它们产生相同的结果。五张表分别是:
customers ← sales ← saleitems → paintings → artists
箭头(希望)显示了表之间的关系。
每个表都有一个名为 的主键id
,而内部表有一个指向另一个名为 的表的外键[othertable]id
。
第一个版本是按上述顺序列出的表的经典连接
SELECT
c.id, c.givenname, c.familyname,
a.givenname, a.familyname
FROM
customers c
JOIN sales s ON c.id=s.customerid
JOIN saleitems si ON s.id=si.saleid
JOIN paintings p ON si.paintingid=p.id
JOIN artists a ON p.artistid=a.id
;
第二个版本JOIN
首先是所有子句,然后是ON
子句,顺序相反。
SELECT
c.id, c.givenname, c.familyname,
a.givenname, a.familyname
FROM
customers c
JOIN sales s
JOIN saleitems si
JOIN paintings p
JOIN artists a
ON p.artistid=a.id
ON si.paintingid=p.id
ON s.id=si.saleid
ON c.id=s.customerid
;
好的,所以它可以工作,但是任何人都可以解释第二个版本是如何工作的吗?为什么从句的顺序必须与ON
从句相反JOIN
?是否可以随机排序JOIN
orON
子句?
我已经在 Microsoft SQL 以及 PostgreSQL 中对此进行了测试。
你不能随机化它们,顺序很重要。如果我们在连接之间添加一些括号,也许您可以更清楚地看到它。
这个查询正在做的是首先加入
sales
,saleitems
然后他们的结果被加入customers
。您不能引用customers
括号连接内的列,因为它不可访问:如果你问我,我会坚持使用第一种编写查询的方式,这种方式对大多数程序员来说更清晰。
在大多数情况下,JOIN 语法要求 JOIN 和 ON 都存在(除非某些特定情况,如 CROSS JOIN 对它没有任何影响)。认为这类似于
BEGIN..END
陈述 - 它们必须是END
与最近的陈述相关BEGIN
的陈述这就是为什么当您以相反的顺序放置 ON 子句时它起作用的原因。但这不是一个好的做法,因为确定哪个条件与哪些表相关会很耗时。特别是如果您在途中松动缩进/格式化。
此外,第二个和所有下一个 JOINS 的额外缩进是不必要的。子句的顺序
JOIN
通常无关紧要(除非您使用强制优化器这样做的查询提示)。我个人会发现它更清晰,如下所示(+ 明确声明 INNER JOIN,+ 从您感兴趣的“事实”表开始安排连接,其他表是您正在检索的事实的描述,如果重要的话,我可以选择将每一列放在单独的行中-如果不重要,我通常将它们放在一行中)。但话又说回来,这是个人编码风格的事情。