说我是否有此查询
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
除了TableA.Hol在哪里或在ON子句中是否更好?
我不确定它是否有所作为,我试图确定它为什么会变慢。也许这与我的加入有关吗?
答案 0 :(得分:0)
这是您的查询:
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;
left join
保留第一个表中的所有行,无论on
子句的计算结果如何。这意味着第一个表中的条件在on
子句中被有效忽略。好吧,并没有完全忽略 - 条件是假的,所以第二个表中的列对于那些行将是NULL
。
因此,left join
中第一个表格的过滤器应该在where
子句中。
后续表的条件应该在on
子句中。否则,这些条件会将外连接转换为内连接。
答案 1 :(得分:0)
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
如果您引用多个表,则可以使用别名来提高可读性。但这与表现无关。
答案 2 :(得分:0)
无论您使用的是JOIN
还是LEFT JOIN
,都可以使用ON
指定相关信息的关联方式,并使用WHERE
进行过滤。
在JOIN
的情况下,过滤的位置无关紧要;为了便于阅读,您应遵循上述规则。
在LEFT JOIN
的情况下,结果可能会有所不同。
如果你这样做
EXPLAIN EXTENDED SELECT ...
SHOW WARNINGS;
你可以看到SQL解析器决定做什么。通常,它将ON
子句移动到WHERE
,表明它们(对于语义)它们所在的位置无关紧要。但是,对于LEFT JOIN
,有些内容必须保留在ON
。
注意另一件事:
FROM a ...
LEFT JOIN b ...
WHERE b.foo = 123
有效地抛弃了LEFT
。 LEFT
和非 - LEFT
之间的区别在于您是否获得b
填充NULLs
的行。但是WHERE b.foo = 123
说你肯定不想要这样的行。因此,为了清楚读者,请不要说LEFT
。
所以,我同意你原来的表述。但我也喜欢所有表的短别名。 确保所有列都符合条件 - 读者可能不知道列中的哪个表格。
你的标题是“多个”连接。我讨论了一个JOIN
;该讲座适用于任意数量的JOINs
。