SQL JOIN: USING、ON或WHERE之间有区别吗?
SQL JOIN: USING、ON和WHERE之间有区别吗?
在SQL中,我们经常使用JOIN来将多个表连接在一起,以便从多个表中检索所需的数据。然而,有些人可能会对使用JOIN时应该使用USING、ON还是WHERE这一问题感到困惑。本文将探讨这个问题的原因以及解决方法。
有人认为使用WHERE来进行连接是一种“肮脏的技巧”,并不符合ANSI的JOIN语法。正确的ANSI JOIN语法应该使用ON子句。例如:
SELECT
p.Product,
o.Order
FROM
Product p
INNER JOIN
Order o
ON
o.OrderID = p.OrderID
使用ON子句来进行连接,而使用WHERE子句来筛选结果更加合理。请记住,除了分组和排序之外,WHERE子句是你筛选结果时使用的最后一项。因此,不应该使用WHERE子句来连接表,因为这样会导致代码更难阅读。例如:
SELECT
p.Product,
o.Order
FROM
Product p
INNER JOIN
Order o
ON
o.OrderID = p.OrderID
WHERE
o.Category = 'IT'
从长远来看,你(开发者)可能不会在未来的工作中使用这段代码,因此代码的可读性和可维护性对于未来接手你代码的人来说非常重要。
当我看到开发者使用WHERE来连接表时,通常说明他们对T-SQL的了解不够。这是我的个人观点。
然而,提问者并没有要求你对是否使用ANSI JOIN语法的“美观”发表意见,而只是关于实现上的可能差异。我认为我的回答完全解答了他的问题。
我完全同意,使用正确的JOIN语法更易读、更易维护。在编辑后,我撤销了我的反对票。但我仍然坚持我的立场:问题是关于可能的性能/算法差异,而不是关于语法。所以这个回答仍然没有回答问题。请我们能够进行一个合理的讨论,而不是互相指责?
没问题,我并没有说其中一种方法在性能上更好。使用正确的方法是正确的事情,就像早上醒来后洗澡一样。你可以不洗澡,但会有人闻到你的气味。正如使用正确的编码规范是正确的事情一样,否则有人会从好的代码中闻到坏代码的味道。
哈哈,我觉得隐式连接可能可以被视为一种代码异味,是吗?
你知道JOIN语法并不是一直可用的,所以在那个时候使用WHERE语法是唯一可用的方法。当然,事情已经改变了,但这解释了为什么有些人可能习惯使用WHERE语法。然而,我同意使用JOIN进行连接,使用WHERE进行其他筛选的观点。
SQL中的JOIN操作是将多个表中的数据进行关联的一种方式。在JOIN操作中,使用的关键字包括USING、ON和WHERE。那么,这些关键字之间是否存在差异呢?下面我们来探讨一下。
首先,需要明确的是,这些关键字在功能上是相似的,它们都可以用来指定JOIN操作的条件。然而,它们在可读性和可维护性方面存在一些差异。
使用ON关键字,可以将JOIN条件直接放在ON子句中,使得代码更加清晰明了。例如:SELECT * FROM a JOIN b ON a.ID = b.ID
,这样的写法直接传达了我们的意图,所有的条件都在同一个地方。
另一方面,使用USING关键字可以在JOIN操作中指定要进行关联的列。例如:SELECT * FROM a JOIN b USING (ID)
,其中的ID就是要进行关联的列。使用USING关键字的好处是,可以减少代码量,使得代码更加简洁。
最后,使用WHERE关键字可以在JOIN操作之后,通过WHERE子句来指定额外的过滤条件。例如:SELECT * FROM a JOIN b ON a.ID = b.ID WHERE a.name = 'John'
,这样可以在JOIN操作之后再进行额外的筛选。
至于性能方面的差异,可能会有一些微小的差别,但并不显著。不同的数据库管理系统可能会对这些关键字进行不同的优化,但一般来说,并不会对性能产生明显的影响。
使用ON关键字可以使得代码更加清晰明了,使用USING关键字可以减少代码量,使用WHERE关键字可以进行额外的筛选。在实际使用中,可以根据自己的需求和习惯选择适合的关键字。无论选择哪种关键字,它们都可以完成JOIN操作的功能。
SQL JOIN:USING、ON或WHERE之间有区别吗?
在性能上没有区别。
然而,第一种风格是ANSI-89风格,在一些地方会被抛弃,包括我的工作场所。第二种风格是ANSI-92风格,更加清晰。
例如:
哪个是JOIN,哪个是过滤?
FROM T1,T2,T3.... WHERE T1.ID = T2.ID AND T1.foo = 'bar' AND T2.fish = 42 AND T1.ID = T3.ID FROM T1 INNER JOIN T2 ON T1.ID = T2.ID INNER JOIN T3 ON T1.ID = T3.ID WHERE T1.foo = 'bar' AND T2.fish = 42
如果你有OUTER JOIN(=*
,*=
),那么第二种风格将按预期工作。第一种风格可能不会,并且在SQL Server 2005+中已经被弃用。
ANSI-92风格更难出错。使用老式风格,如果你忘记添加条件,很容易得到一个笛卡尔积(交叉连接)。使用ANSI-92风格将会得到一个语法错误。
编辑:进一步澄清
- 不使用"join the where"(隐式)的原因是在外连接中结果不准确。
- 如果你同时使用显式OUTER JOIN和隐式INNER JOIN,你仍然会得到不准确的结果,并且使用上不一致。
这不仅仅是语法问题:它关乎一个语义上正确的查询。
2011年12月编辑
SQL Server的逻辑查询处理顺序是FROM、ON、JOIN、WHERE...
因此,如果你混合使用"implicit WHERE inner joins"和"explicit FROM outer joins",你很可能得不到预期的结果,因为查询是模糊的...
你知道是否有文档记录了这只是一个语法的改变吗?
ANSI-92取代了ANSI-89?实际上,这是为了清晰和可维护性。你似乎反对JOIN语法...
Timmer 92 > 89,我最后一次检查时是这样的。
Timmer:我再试一次...不使用"join the where"(隐式)的原因是外连接的危险。然后,如果你使用显式OUTER JOIN + 隐式INNER JOIN,你仍然会得到不准确的结果,并且使用上不一致。这不仅仅是语法问题:它关乎语义。
Timmer - 那么你还在寻找什么其他的文档呢?他给出了实用的信息和良好的编程实践。
"哪个是JOIN,哪个是过滤?"——这些术语是主观的,所以这个问题是有偏见的:没有看到完整的查询和知道其目的,无法回答。对于INNER JOIN来说,可能没有区别。如果它们是OUTER JOIN,将筛选条件改为连接条件,查询结果可能会根据NULL值而改变,但是在不知道设计者意图的情况下,我不能确定这是否是"错误"。
:不确定你想说什么。你支持在WHERE语法中使用已弃用的OUTER JOIN吗?你理解为什么WHERE中的OUTER JOIN是模糊的吗?你不喜欢清晰和语义正确吗?
难道你的意思不是经常在WHERE子句中使用ON子句产生的NULL进行过滤吗?
:接受你的观点:我不应该尝试使用口语化或鼓励他人这样做!
逗号连接和交叉连接的唯一区别是逗号连接的优先级较低。尽管这是不混合使用它们的一个很好的理由。逗号一直都是ANSI/ISO/标准的。