如果我有多个LOJ
和多个INNER JOINS
,那么我应该使用正确的标准语法结构吗?
示例方案
这是正确使用的结构:
SELECT
#A.UserId,
#A.MeasureA,
#B.MeasureB,
#C.MeasureC,
D = COALESCE(#D.MeasureD,0.),
E = COALESCE(#E.MeasureE,0.)
FROM
#A
JOIN #B
ON #A.UserId = #B.UserId
JOIN #C
ON #A.UserId = #C.UserId
LEFT OUTER JOIN #D
ON #A.UserId = #D.UserId
LEFT OUTER JOIN #E
ON #A.UserId = #E.UserId
或者LOJ应该在#A上的子查询中应用吗?
SELECT
X.UserId,
X.MeasureA,
#B.MeasureB,
#C.MeasureC,
X.D,
X.E
FROM
(
SELECT
#A.UserId,
#A.MeasureA,
D = COALESCE(#D.MeasureD,0.),
E = COALESCE(#E.MeasureE,0.)
FROM #A
LEFT OUTER JOIN #D
ON #A.UserId = #D.UserId
LEFT OUTER JOIN #E
ON #A.UserId = #E.UserId
) X
JOIN #B
ON X.UserId = #B.UserId
JOIN #C
ON X.UserId = #C.UserId
答案 0 :(得分:2)
当您使用左外连接时,意图是其中一个表保留其所有行,而不管其他表中的匹配。
我首选的结构是将此表放在第一位:
select . . .
from <really important table> t left outer join
. . .
如果稍后在from
子句中有内部联接,则这不起作用,因为这些会过滤掉没有匹配的行。
就您的查询而言,我认为第一个符合您的期望。第二个发生以执行您想要的操作,因为您只加入了id
列。但结构非常危险。如果您的后续内连接之一位于#E
的列上,那么它会(无意中)将左连接更改为内连接。
因此,先将内连接放入,然后放入左外连接。
答案 1 :(得分:0)
要记住的一件事是,除非你做一些非常时髦的事情,否则两个结构不同的等价查询可能会被优化器完全相同地解释。你提出的两个问题几乎可以肯定。
考虑到这一点,唯一正确的&#34;结构是您发现最容易阅读和维护的结构。就个人而言,我会先进行第一个查询,因为它会直截了当地说出它的所作所为。
对于实际提出的问题要更加明确一点:这里适用的标准不是SQL标准,而是编码标准:不要让事情变得比他们需要的更复杂。
答案 2 :(得分:0)
作为应用程序开发人员,我们信任框架,为什么我们不能信任SQL引擎来完成它的工作呢?第一种语法是SQL所期望的,在不必要时不要复杂化。
然而,如果A - >; D是一对多; A - &gt; E是一对多,D和E之间没有关系。我将GROUP BY D和E匹配独立子查询中的行,然后再将其插回主查询。
但是,这种做法似乎不适用于您的用例。
答案 3 :(得分:-1)
您可以在一个查询中完成所有操作,实际上不需要使用子查询来编写它。只是提醒一下LOJ是如何工作的,你会清楚地看到它!