对于多个表上的复杂联接,是否应该使用sql JOIN关键字?
我有以下要求:对于多个表上的复杂联接,是否应该使用sql JOIN关键字?,sql,join,Sql,Join,我有以下要求: select * from tbA A, tbB B, tbC C, tbD D where A.ID=B.ID and B.ID2= C.ID2 and A.ID=D.ID and C.ID3=D.ID3 and B.ID4=D.ID4 and A.Foo='Foo' 我多次听说这种连接语法被贬低了,我应该使用'join'关键字 在这样一个复杂的联接(多个表在属于不同表的多个列上联接)中,我如何做到这一点?您认为这种最佳实践在这里仍然适用吗?我发现
select *
from tbA A, tbB B, tbC C, tbD D
where
A.ID=B.ID and B.ID2= C.ID2 and A.ID=D.ID and C.ID3=D.ID3 and B.ID4=D.ID4
and
A.Foo='Foo'
我多次听说这种连接语法被贬低了,我应该使用'join'关键字
在这样一个复杂的联接(多个表在属于不同表的多个列上联接)中,我如何做到这一点?您认为这种最佳实践在这里仍然适用吗?我发现连接语法更容易理解
select *
from tbA A
inner join tbB B on a.id = b.id
inner join tbC C on b.id2 = c.id2
inner join tbD D on a.id = d.id and c.id3 = d.id3 and b.id4 = d.id4
where A.Foo='Foo'
现在,您可以清楚地看到数据是如何连接在一起的,它并不是一个非常复杂的连接
顺便说一句,您的示例中的数据库设计带有强烈的缺乏规范化的味道。通常,您应该有一个表连接到多个表(a.bid=b.bid-join-c-on-a.cid=c.cid)或一个链(a.bid=b.bid-join-c-on-b.cid=c.cid)
编辑。添加了可选的关键字internal,它不会改变结果,但会使结果更加清晰
SELECT *
FROM tba AS a
JOIN tbb AS b ON a.id = b.id
JOIN tbc AS c ON b.id2 = c.id2
JOIN tbd AS d ON a.id = d.id AND c.id3 = d.id3 AND b.id4 = d.id4
WHERE
a.foo = 'Foo'
尽管我很难想象有什么需要。举个例子,或者更具描述性的表名?
JOIN
语法更清晰(虽然我个人更喜欢在简单的情况下使用WHERE
语法),而且更重要的是,可以以更清晰的方式处理内部的和外部的连接
其中
未被弃用,并且可能永远不会被弃用
只有在不同的外部联接
解决方案(如(*)
和(+)
)被弃用的情况下,才不推荐使用它
在WHERE
中,没有什么是你不能用JOIN
做的,但反之亦然。这是品味的问题,但我更喜欢JOIN关键字。它使逻辑更加清晰,并且与它附带的左外连接语法更加一致。请注意,还可以使用内部联接,它与联接同义
语法是
a JOIN b
ON expression relating b to all of the tables before
b本身可以是一个连接。对于内部联接,这无关紧要,但是对于外部联接,您可以像下面这样控制联接的顺序:
select * from
a left join
d join c
on d.i = c.i
on a.k = d.k
此处a与d和c之间的内部连接左连接
以下是您的疑问:
select *
from tbA A
join tbB B on A.ID = B.ID
join tbC C on B.ID2 = C.ID2
join tbD D on A.ID = D.ID and C.ID3 = D.ID3 and B.ID4 = D.ID4
where
A.Foo='Foo'
你故意重复了两次“a.id=b.id”吗?实际上应该是a.id=d.id:)后更正。顺便说一句,命名的这个简单问题清楚地说明了设计不正确的原因。@wwosik:这些名称当然不是“真实”的表名。我理解:)可能是我在遇到有字段id的人的表时提到的一些回忆,id2和id3…使用ANSI格式的好处是连接逻辑与过滤逻辑分离。一眼就能看出这些表之间的关系。是的,它已被弃用。是的,你应该清理你的sql。@Chris:看来这个语法的用法并没有遭到反对,而*(做左连接)的用法是(在另一个答案中有详细说明)。关于SQL,我只是作为一个例子写的。连接越复杂,使用ANSII标准语法就越重要,因为它不太容易意外地使用交叉连接。此外,旧式语法中的左连接和右连接已被弃用,即使现在也不应使用,因为它们经常返回错误的结果。HLGEM:错误的结果?你能详细说明一下吗?的确。现在我记得在联接中使用*时看到此消息