简体   繁体   English

在多重连接中放置条件的位置?

[英]Where to put conditions in Multiple Joins?

Say if I have this query说如果我有这个查询

SELECT TableA.Id, TableA.Number, TableA.Name, TableA.HOl, TableB.Contact, TableC.activity
FROM TableA
left JOIN TableB on TableA.Id = TableB.TableA_Id 
left join TableC on TableB.userid = TableC.userid
where TableA.hol = 50 
order By TableA.Id

Is it better to but the TableA.Hol in the where or in the ON clause?在 where 或 ON 子句中使用 TableA.Hol 是否更好?

I am not sure if it makes a difference, I am trying to determine why it slow.我不确定它是否有所作为,我试图确定为什么它会变慢。 Maybe it something else with my joins?也许它与我的加入有关?

This is your query:这是您的查询:

select TableA.Id, TableA.Number, TableA.Name, TableA.HOl, TableB.Contact, TableC.activity
from TableA left join
     TableB
     on TableA.Id = TableB.TableA_Id left join
     TableC
on TableB.userid = TableC.userid
where TableA.hol = 50 
order By TableA.Id;

A left join keeps all rows in the first table, regardless of what the on clause evaluates to. left join保留第一个表中的所有行,而不管on子句的计算结果如何。 This means that a condition on the first table is effectively ignored in the on clause.这意味着第一个表上的条件在on子句中被有效地忽略。 Well, not exactly ignored -- the condition is false so the columns from the second table will be NULL for those rows.好吧,并没有完全忽略——条件为假,因此第二个表中的列对于这些行将为NULL

So, filters on the first table in a left join should be in the where clause.因此, left join第一个表的过滤器应该在where子句中。

Conditions on subsequent tables should be in the on clause.后续表的条件应在on子句中。 Otherwise, those conditions will turn the outer join into an inner join.否则,这些条件会将外连接变成内连接。

SELECT A.Id, A.Number, A.Name, A.HOl, B.Contact, C.activity
FROM TableA A
LEFT OUTER JOIN TableB B
ON (A.Id = B.TableA_Id)
LEFT OUTER JOIN TableC C
ON (B.userid = C.userid)
AND A.hol = 50
ORDER BY A.Id

If you are referencing more than one table you can use an alias which improves readability.如果您引用多个表,您可以使用别名来提高可读性。 But this has nothing to do with performance.但这与性能无关。

Regardless of whether you are using JOIN or LEFT JOIN , use ON to specify how the tables are related and use WHERE to filter.无论您使用JOIN还是LEFT JOIN ,都使用ON指定表的关联方式并使用WHERE进行过滤。

In the case of JOIN , the it does not matter where you put the filtering;JOIN的情况下,将过滤放在哪里并不重要; it is for readability that you should follow the above rule.为了便于阅读,您应该遵循上述规则。

In the case of LEFT JOIN , the results are likely to be different.LEFT JOIN的情况下,结果可能会有所不同。

If you do如果你这样做

EXPLAIN EXTENDED SELECT ...
SHOW WARNINGS;

you can see what the SQL parser decided to do.您可以看到 SQL 解析器决定做什么。 In general, it moves ON clauses are to WHERE , indicating that it does not matter (to the semantics) which place they are.通常,它将ON子句移动到WHERE ,表明它们在哪个位置无关紧要(对语义而言)。 But, for LEFT JOIN , some things must remain in the ON .但是,对于LEFT JOIN ,有些东西必须保留在ON

Note another thing:注意另一件事:

FROM a ...
LEFT JOIN b ...
WHERE b.foo = 123

effectively throws out the LEFT .有效地抛出LEFT The difference between LEFT and non- LEFT is whether you get rows of b filled with NULLs . LEFT和非LEFT之间的区别在于是否让b行填充了NULLs But WHERE b.foo = 123 says you definitely do not want such rows.但是WHERE b.foo = 123表示您绝对不想要这样的行。 So, for clarity for the reader, do not say LEFT .因此,为了读者清楚起见,不要说LEFT

So, I agree with your original formulation.所以,我同意你原来的表述。 But I also like short aliases for all tables.但我也喜欢所有表的短别名。 Be sure to qualify all columns -- the reader may not know which table a column is in.确保限定所有列——读者可能不知道列在哪个表中。

Your title says "multiple" joins.您的标题说“多个”连接。 I discussed a single JOIN ;我讨论了一个JOIN the lecture applies to any number of JOINs .该讲座适用于任意数量的JOINs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM