隐式SQL联接可以';不行?

隐式SQL联接可以';不行?,sql,join,Sql,Join,我从来没有学习过连接是如何工作的,但是仅仅使用select和where子句就足以满足我所做的所有查询。是否存在使用where子句无法获得正确结果而必须使用JOIN的情况?如果是,请有人举个例子好吗?谢谢。是的。在进行外部联接时。你可以阅读连接。连接一点也不难理解,因此您应该立即开始学习(并在适当的情况下使用它们) 任何时候想要合并两个表的结果,都需要将它们联接起来。例如: 用户表: ID FirstName LastName UserName Password 和地址表: ID UserID

我从来没有学习过连接是如何工作的,但是仅仅使用select和where子句就足以满足我所做的所有查询。是否存在使用where子句无法获得正确结果而必须使用JOIN的情况?如果是,请有人举个例子好吗?谢谢。

是的。在进行外部联接时。你可以阅读连接。连接一点也不难理解,因此您应该立即开始学习(并在适当的情况下使用它们)

任何时候想要合并两个表的结果,都需要将它们联接起来。例如:

用户表:

ID
FirstName
LastName
UserName
Password
和地址表:

ID
UserID
AddressType (residential, business, shipping, billing, etc)
Line1
Line2
City
State
Zip
其中,单个用户可以列出其家庭和业务地址(或发货地址和账单地址),或者根本没有地址。使用简单的
WHERE
子句不会获取没有地址的用户,因为地址位于不同的表中。要立即获取用户地址,您需要按以下方式进行连接:

SELECT *
FROM Users
LEFT OUTER JOIN Addresses
    ON Users.ID = Addresses.UserID
WHERE Users.UserName = "foo"

有关不同联接的更深入定义及其工作方式,请参阅。

默认情况下,隐式联接语法使用内部联接。有时可以修改隐式连接语法来指定外部连接,但根据我的经验,这取决于供应商(我知道oracle有(-)和(+)表示法,我相信sqlserver使用*=)。所以,我相信你的问题可以归结为理解内部联接和外部联接之间的差异

我们可以使用一个简单的查询查看一个简单的内部连接与外部连接示例

隐式内部联接:

select a.*, b.*
from table a, table b
where a.id = b.id;
上述查询将仅返回“a”行在“b”中的“id”字段中有匹配行的行

显式外部联接:

select * from
table a LEFT OUTER JOIN table b
on a.id = b.id;
上面的查询将返回a中的每一行,无论它在“b”中是否有匹配的行。如果“b”不存在匹配项,“b”字段将为空

在这种情况下,如果希望返回“a”中的每一行,而不管它是否有对应的“b”行,则需要使用外部联接

正如我所说,根据数据库供应商的不同,您仍然可以使用隐式连接语法并指定外部连接类型。但是,这会将您与该供应商联系起来。此外,任何不熟悉专门语法的开发人员都可能难以理解您的查询

是否存在使用where子句无法获得正确结果而必须使用JOIN的情况

每当查询涉及两个或多个表时,都会使用联接。非常适合用图片和示例结果集显示连接中的差异

如果联接条件在
WHERE
子句中,则使用ANSI-89联接语法。ANSI-92格式中较新的联接语法的原因是,它使左联接在各种数据库中更加一致。例如,Oracle在可选的一侧使用了
(+)
,而在SQL Server中您必须使用连接:

SELECT a.MainID, b.SubValue AS SubValue1, b.SubDesc AS SubDesc1, c.SubValue AS SubValue2, c.SubDesc AS SubDesc2
FROM MainTable AS a
LEFT JOIN SubValues AS b ON a.MainID = b.MainID AND b.SubTypeID = 1
LEFT JOIN SubValues AS c ON a.MainID = c.MainID AND b.SubTypeID = 2
一方面,我看不到通过使用简单的WHERE子句连接表来获得相同结果的方法。
此外,WHERE子句中用于进行左连接和右连接(*=和=*)的常用语法正在逐步淘汰,

隐式连接已经过时20多年了。为什么你会考虑和他们一起编写代码?< /P> 是的,它们会产生显式联接所没有的问题。说到SQL Server,不能保证左连接和右连接隐式语法返回正确的结果。有时,它们返回交叉连接而不是外部连接。这是一件坏事。至少在SQLServer2000时代也是如此,而且它们正在被逐步淘汰,所以使用它们是一种非常糟糕的做法

隐式连接的另一个问题是,由于忘记了其中一个where条件,特别是在连接太多表时,很容易意外地执行交叉连接。通过使用显式联接,如果忘记放入联接条件,并且必须显式指定交叉联接,则会出现语法错误。同样,这会导致查询返回不正确的值,或者通过使用distinct来消除交叉连接(最好是低效的)而得到修复

此外,如果您有一个交叉连接,那么在一年内进行更改的维护开发人员不知道在您使用隐式连接时它是否是有意的

我相信一些orm现在也需要显式连接

此外,如果您使用隐式联接是因为不了解联接是如何操作的,那么很有可能您编写的代码实际上没有返回正确的结果,因为您不知道如何计算正确的结果,因为您不了解联接的作用


如果您编写任何风格的SQL代码,都没有理由不完全理解联接。

Oracle使用其特殊的联接操作符
(+)
(SQL Server过去支持联接谓词上的
*=
=*
,但现在不再支持)。但是简单的
完全联接
不能单独使用隐式联接:

选择f.title、a.first\u name、a.last\u name
来自电影f
完全加入电影演员fa ON f.film\u id=fa.film\u id
fa.actor\u id=a.actor\u id上的完全联接actor a
这就产生了所有电影及其演员,包括所有没有演员的电影,以及没有电影的演员。要仅使用隐式联接来模拟这种情况,需要联合

--内部连接部件
选择f.标题、a.名字、a.姓氏
来自电影f,电影演员fa,演员a
其中f.film_id=fa.film_id
fa.actor\u id=a.actor\u id
--左结合部
联合所有
选择f.title、null、null
来自电影f
不存在的地方(
选择1
来自电影演员fa
其中fa.film\u id=f.film\u id
)
--右连接部件
联合所有
选择空,a.名字,a.姓氏
演员a
不存在的地方(
选择1
从电影_