sql作为维恩图加入

时间:2012-12-21 21:22:34

标签: sql mysqli visualization set-theory

我在理解sql中的连接时遇到了麻烦,并且遇到了这个我认为可能对我有用的图像。问题是我不完全理解它。例如,图像右上角的连接,它将整个B圆圈的颜色设置为红色,但只有A的重叠。图像使得它看起来像圆圈B是sql语句的主要焦点,但是sql语句本身,从A开始(从A中选择,加入B),向我传达了相反的印象,即A将成为sql语句的焦点。

同样,下面的图片仅包含来自B圈的数据,那么为什么在连接语句中包含A?

问题:从右上方顺时针工作并在中心完成,有人可以提供有关每个sql图像表示的更多信息,解释

a)为什么在每种情况下都需要加入(例如,特别是在没有数据来自A或B的情况下,即只有A或B而不是两者都被着色的情况下)

b)以及任何其他详细说明为什么图像是sql

的良好表示的细节

sql join diagram

5 个答案:

答案 0 :(得分:51)

我同意Cade关于维恩图的局限性。更合适的视觉表现可能就是这样。

Tables

SELECT A.Colour,B.Colour from A CROSS JOIN B SQL Fiddle

交叉连接(或笛卡尔积)使用两个表中的每个行组合生成结果。每个表有4行,因此在结果中产生16行。

Cross Join

SELECT A.Colour,B.Colour from A INNER JOIN B ON A.Colour = B.Colour SQL Fiddle

内部联接在逻辑上返回交叉联接中与联接条件匹配的所有行。在这种情况下,有五个。

Inner Join

SELECT A.Colour,B.Colour from A INNER JOIN B ON A.Colour NOT IN('Green','Blue')SQL Fiddle

内连接条件不一定是相等条件,也不需要引用两个(甚至任何一个)表中的列。评估交叉连接的每一行上的A.Colour NOT IN ('Green','Blue')返回。

inner 2

对于交叉连接中的每一行,1=1的内部连接条件将评估为true,因此两者是等效的(SQL Fiddle)。

SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour SQL Fiddle

外连接的逻辑评估方式与内连接的方式相同,只是如果左表中的一行(左连接)没有与右表中的任何行连接,则它将保留在结果中右侧列的NULL值。

LOJ

SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour IS NULL SQL Fiddle

这只是限制了之前的结果,只返回B.Colour IS NULL的行。在这种特殊情况下,这些行将被保留,因为它们在右侧表中没有匹配,并且查询返回表B中不匹配的单个红色行。这被称为反半连接。

IS NULL测试选择一个不可为空的列,或者连接条件确保排除任何NULL值以使此模式正常工作并且除了未匹配的行之外,请避免仅返回恰好具有NULL值的行。

loj is null

SELECT A.Colour,B.Colour from A RUST OUTER JOIN B ON A.Colour = B.Colour SQL Fiddle

右外连接的作用类似于左外连接,除了它们保留右表中不匹配的行,null扩展左侧列。

ROJ

SELECT A.Colour,B.Colour from A FULL OUTER B B ON A.Colour = B.Colour SQL Fiddle

完全外连接组合了左连接和右连接的行为,并保留左右表中不匹配的行。

FOJ

答案 1 :(得分:9)

维恩图适用于表示集合操作,如UNION,INTERSECTS,EXCEPT等。

只有那些像EXCEPT这样的设置操作是用LEFT JOIN WHERE来模拟的,rhs.KEY是NULL,这个图是准确的。

否则会产生误导。例如,如果连接条件不是1:1,则任何连接都可能导致行相乘。但是只允许集合包含不同的成员,因此不能将它们表示为集合操作。

然后有CROSS JOIN或INNER JOIN ON 1 = 1 - 这既不类似于INNER JOIN,如图所示,也不能用Venn图真正描述产生的集合。更不用说所有其他可能的三角形连接,自我和反连接,如:

lhs INNER JOIN rhs ON rhs.VALUE < lhs.VALUE (triangular)

SELF self1
INNER JOIN SELF self2
    ON self2.key <> self1.key
    AND self1.type = self2.type

(自我交叉和反连接以找到除了你自己以外的所有类似家庭成员 - self1和self2是相同的集合,结果是一个合适的子集)

在教程的前几分钟坚持加入键可能没什么问题,但这可能会导致学习联接的路径很差。我想这就是你找到的。

Venn Diagrams通常以这种方式代表JOIN的想法需要消失。

答案 2 :(得分:8)

我认为你的主要潜在混淆是,当(例如)只有A以红色突出显示时,你会认为“查询只返回来自A <的数据 / em>“,但实际上它意味着”查询仅返回A具有记录“的情况下的数据。该查询可能仍包含来自B的数据。(对于B 有记录的情况,查询将替换NULL。)

  

同样,下面的图片仅包含来自B圈的数据,那么为什么在连接语句中包含A?

如果您的意思是 - A完全为白色的图像,B的部分与A不重叠的红色新月形状,则: A出现在查询中的原因是,A是查找B中需要排除的记录的原因。 (如果A没有出现在查询中,那么维恩图就没有A,它只会显示B,并且无法区分所需的记录来自不受欢迎的人。)

  

图像看起来像圆圈B是sql语句的主要焦点,但是sql语句本身,从A开始(从A中选择,加入B),给我带来了相反的印象,即A会是sql语句的重点。

非常正确。因此,RIGHT JOIN相对不常见;虽然使用LEFT JOIN的查询几乎总是可以重新排序以使用RIGHT JOIN代替(反之亦然),但通常人们会使用LEFT JOIN编写查询,而不是使用{{ 1}}。

答案 3 :(得分:-1)

当您进行连接时,您的两个表可能无法完美匹配。具体来说,A中的某些行可能与B中的任何行不匹配,或者A中的重复行与B中的单行匹配,反之亦然。

当发生这种情况时,您可以选择:

  1. 对于每个A,如果有的话,可以选择一个有效的B. (左上)
  2. 将每对完全匹配(丢弃任何缺少A或B的中心)
  3. 对于每个B,如果有一个(右上角)
  4. ,则选择一个有效的A.
  5. 采取一切(左下)
  6. 左右中心在技术上是连接的,但是没有意义的;它们可能更有效地写成SELECT <select_list> FROM TableA A WHERE A.Key NOT IN (SELECT B.Key FROM TableB B)(或相反)。

    直接回答您的疑惑,RIGHT JOIN说“以下表达式是此查询的焦点”。 右下方很奇怪,我没有理由为什么你会这么想。它返回两个外部中间查询的结果,并在相对表的所有列中与NULL混合在一起。

答案 4 :(得分:-1)

对于正确的连接,是的语法可能令人困惑,但是它似乎是它的样子。当你说“TableA RIGHT JOIN TableB”时,确实说TableB是你所指的主表,而TableA只挂在它有匹配记录的地方。这在查询中读取很奇怪,因为TableA首先被列出,所以你的大脑会自动为它分配更多优先级,即使TableB确实是查询中更重要的表。因此,您很少在实际代码中看到正确的连接。

因此,不要使用A和B,而是让两件易于跟踪的事情。据说我们有两个人的信息表,ShoeSize和IQ。你有一些人的ShoeSize信息,一些人的一些智商信息。并且在两个表上都有一个PersonID可以加入。

从右上方顺时针方向(即使这是从一些更复杂和人为的案例开始):

  • ShoeSize RIGHT JOIN IQ - &gt;给我所有的IQ信息。如果我们有这些人,请包含任何ShoeSize信息。
  • ShoeSize RIGHT JOIN IQ WHERE ShowSize.PersonID = NULL - &gt;给我所有的IQ信息,但仅适用于没有任何鞋码信息的人
  • ShoeSize FULL OUTER JOIN IQ WHERE ShoeSize.PersonID = NULL AND IQ.PersonID = NULL - &gt;只给那些没有智商信息的人提供鞋码信息,加上没有鞋码信息的人的智商信息
  • ShoeSize FULL OUTER JOIN IQ - &gt;给我一切,所有鞋码和所有IQ数据。如果任何ShoeSizes和IQ记录具有相同的PersonID,请将它们包含在一行中。
  • ShoeSize LEFT JOIN IQ WHERE IQ.PersonID = NULL - &gt;给我所有的鞋码信息,但仅适用于没有IQ信息的人
  • ShoeSize LEFT JOIN IQ - &gt;给我所有的鞋码信息。如果我们有这些人,请包含任何IQ信息。