JOIN
类型之间有什么区别?SELECT *
FROM user u
INNER JOIN telephone t ON t.user_id = u.id
SELECT *
FROM user u
LEFT OUTER JOIN telephone t ON t.user_id = u.id
我什么时候应该使用一个或另一个?
#1 楼
内部联接将只选择两个指定表中已联接键的记录。
左外部联接将选择第一个表中的所有记录,以及第二个表中与联接键匹配的任何记录。
右外部联接将从第二个表中选择所有记录,以及第一个表中与联接的键匹配的所有记录。
在第一个示例中,您将仅返回一个列表用户和电话号码,如果该用户至少有一条电话记录。
在第二个示例中,您将返回所有用户的列表,以及所有可用的电话记录(如果没有)无法使用,您将获得
NULL
作为电话值)。#2 楼
每当有人问这个问题时,都有答案:http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
希望它能帮助您理解,
评论
我从事联接工作已有20年了,那些图对我来说似乎很令人困惑。
– Hogan
2011年1月4日18:32
我和@Hogan在一起-ven图表不是对此最好的解释..显示返回哪些组合的网格可能会更好。
–乔
2011年1月5日19:19
这说明您不了解维恩图。它们确实与联接的类型紧密相关,但是请记住,它们是帮助了解新联接的工具。如果您已经学习过加入不同概念的连接,那么注定对您来说是陌生的。没问题,但这也不是图表实用性的良好指标。
–詹姆斯·瑞安(JamesRyan)
2013年12月13日16:47
@jamesryan是不正确的,它们之间的关系不完美,连接类似于集合的笛卡尔积,而不是交集和并集,维恩图模拟仅在您通过唯一键进行连接时才起作用,如果您重复了键,那么您将丢失笛卡尔积方面。
–将
16年5月31日在22:26
我非常不同意,维恩图已经有了很好定义的解释,设置了交集和并集。当您通过非唯一键进行联接时,联接不符合这种解释。我认为您对维恩图的解释过于广泛。
–将
16年1月1日在23:00
#3 楼
内部联接返回可以根据联接条件组合的行。外部联接从第一个表返回这些行和所有行...
...左联接
。 ..从第二个表中进行正确联接
...从两个表中进行完全联接
选择何时使用一个或另一个是确定所需数据的问题。对于您的示例,如果您只需要电话中具有与用户ID匹配的user_id的记录,则使用内部联接。如果您还希望包括没有匹配电话条目的用户行,则左连接将是适当的。
有关更多信息,请参见StackOverflow上的此问题。
#4 楼
如果您有2个如下表:Table1 : A1 B1 Table2 : B2 C2
- - - -
1 2 1 1
2 4 2 4
3 5 5 2
如果使用内部联接,您将得到:
A1 B1 B2 C2
- - - -
1 2 2 4
3 5 5 2
如果使用完全外部联接,则得到:
A1 B1 B2 C2
- - - -
1 2 2 4
3 5 5 2
2 4 NULL NULL
NULL NULL 1 1
如果使用左侧外部联接,则得到:
A1 B1 B2 C2
- - - -
1 2 2 4
3 5 5 2
2 4 NULL NULL
#5 楼
明确设计外部联接以使其结果为空,因此通常应避免使用外部联接。从关系上讲,这是一种of弹枪的婚姻:它迫使表成为一种联合体-是的,我的意思是说联合体,而不是联接-即使有问题的表不符合通常的联合体要求。实际上,这样做是通过在进行联合之前用一个空值填充一个或两个表,从而使它们毕竟符合那些通常的要求。但是,没有理由不应该使用适当的值而不是空值来进行填充,例如以下示例:SELECT SNO , PNO
FROM SP
UNION
SELECT SNO , 'nil' AS PNO
FROM S
WHERE SNO NOT IN ( SELECT SNO FROM SP )
也可以通过以下方法获得相同的结果:将SQL外连接运算符与
COALESCE
结合使用,如下所示:SELECT SNO , COALESCE ( PNO , 'nil' ) AS PNO
FROM ( S NATURAL LEFT OUTER JOIN SP ) AS TEMP
“ SQL和关系理论:如何准确编写”中对外部联接(4.6)的说明SQL代码”,作者:CJ Date
#6 楼
内部联接是一个联接,其中显示的唯一结果是两个表中的键均在其中的结果。外部联接将在一个表中显示所有键的结果,第一个表的左联接,第二个表的右联接。例如:假设table1具有以下主键和数据对:(1,a),(2,b),(3,c)
也说table2具有以下主键和数据对:(1,fun),(3,can),(4,巧遇)
因此,table1与table2在主键上的内部联接将产生以下结果三元组(首先使用公用主键,第二个是第二个表,第二个是第二个表):(1,a,fun),(3,c,can)
主键上的table1到table2的左外部联接将产生以下结果三元组(与上面相同的格式):(1,a,fun),(2,b,NULL),(3,c,can)
主键上的table1和table2的右外部连接将产生以下结果三元组(与上述格式相同):(1,a,fun),(3,c,can),(4 ,则为NULL)
我希望这能很好地解释这一概念。
#7 楼
让我尝试更直观地描述它。内部联接向用户显示具有一个或多个电话及其电话号码的用户。
左外部联接还列出了没有电话的“用户”。
#8 楼
既然您已经询问了何时使用什么内容,那么这是一个带有查询的场景-根据需要选择要使用的内容。数据:
表用户有10条记录。
表Phoneno具有6条记录(具有1:1关系,这意味着PhoneNo中的一项仅引用Users中的一项,而PhoneNo中只有一项可以引用Users中的给定项)。
要求1:向所有用户显示其电话号码。忽略没有电话号码的用户。
查询:
SELECT u.uid, u.name, p.phonno
FROM user u
INNER JOIN phones p ON p.uid = u.uid
结果:显示6个具有电话号码的用户
要求2:向所有用户显示其电话号码。如果用户没有电话显示屏'N / A'(不可用)
查询:
SELECT u.uid, u.name, ifnull(p.phonno,'N/A')
FROM user u
LEFT OUTER JOIN phones p ON p.uid = u.uid
结果:
显示所有10条记录
注意:ifnull是MySql语法,用于转换空值。当phonno为null时,我使用此函数使数据库引擎显示“ N / A”。如果使用其他DBMS,请寻找适当的功能。在SQL Server中,必须使用
CASE
语句。希望对您有所帮助。
评论
这适合作为DBA问题吗?对我来说,这似乎是一个编码问题。@David您对Meta的想法
如果您认为该网站有误,请@David然后是VtC。我们可以随时重新打开。
我认为这是一个很好的问题,非常适合该网站。
除非有新手可以调整DB性能,否则需要将其移出DBA:P