MySQL内部加入结果

时间:2013-05-20 13:34:30

标签: mysql sql database

我对MySQl中的内部联接有疑问。由于我对MySQL的理解有限,内联接产生的结果表只包含两个表中存在的行。也就是说,例如,如果table1包含Joe的行和Sally的行,而table2只包含Sally的一行,则内部联接只包含一行:Sally的行。

例如:

在包含2个表的数据库中

表1(宠物)

petName petType
Unicorn Horse
Pegasus Horse
Lion Cat

表2(颜色)

petName petColor
Unicorn white
Unicorn silver
Fish Gold

使用查询

SELECT * FROM Pet,Color WHERE Pet.petName = Color.petName

为什么是查询结果?

petName petType petName petColor
Unicorn Horse   Unicorn white
Unicorn Horse   Unicorn silver

为什么在表1中只有1只“独角兽马”时,第二排有“独角兽马”?我是否正确地说MySQL在表1和表2中都匹配术语“Unicorn”,并列出两个表中具有单词“Unicorn”的行。但是这样做会导致

petName petType petName petColor
Unicorn Horse   Unicorn white
<   NULL   >   Unicorn silver

MySQL会自动将值替换为表1中的“Unicorn Horse”行,因为它与查询中使用的“Unicorn”关键字相匹配吗?

如果是这样,那将是什么意思,因为MySQL只会给我第二行中的冗余数据,我没有用?此外,我是否可以使用

来解决这个问题
SELECT * FROM Pet LEFT JOIN Color
ON Pet.petName=Color.petName
WHERE Pet.petName="Unicorn"?

我在PHP&amp;中看到了这个例子。 MYSQL for Dummies似乎无法得到它。 如果某种善意的人能澄清这一点,我将不胜感激。

6 个答案:

答案 0 :(得分:3)

结果如预期。您将在两个表上使用列PetName连接两个表。 Unicorn HorsePet在结果集中显示两次,因为它在表Color上的两个记录上有匹配。

要进一步了解联接,请访问以下链接:

答案 1 :(得分:2)

如果您执行了SELECT * from Pet, Color(没有WHERE子句),您将获得以下回复:

petName petType petName petColor
Unicorn Horse   Unicorn white
Pegasus Horse   Unicorn white
Lion    Cat     Unicorn white
Unicorn Horse   Unicorn silver
Pegasus Horse   Unicorn silver
Lion    Cat     Unicorn silver
Unicorn Horse   Fish    Gold
Pegasus Horse   Fish    Gold
Lion    Cat     Fish    Gold

这称为CROSS JOIN; SQL服务器将从表1中获取每一行,并将其与表2中的每一行匹配。

当您添加WHERE Pet.petName = Color.petName时,SQL服务器将过滤掉该子句不真实的所有行。因此,由于定义petName的唯一petColorUnicorn,因此您只剩下

petName petType petName petColor
Unicorn Horse   Unicorn white
Unicorn Horse   Unicorn silver

如果您的查询改为WHERE Pet.petName != Color.petName,则可以使用补码或

petName petType petName petColor
Pegasus Horse   Unicorn white
Lion    Cat     Unicorn white
Pegasus Horse   Unicorn silver
Lion    Cat     Unicorn silver
Unicorn Horse   Fish    Gold
Pegasus Horse   Fish    Gold
Lion    Cat     Fish    Gold

如果您只希望Pet中有一行定义了Color,则可以使用

SELECT * FROM Pet 
  WHERE EXISTS (SELECT * FROM Color where Color.petName = Pet.petName)

会返回

petName petType
Unicorn Horse  

此查询实质上意味着“从Pet中选择所有行,其中至少有一个Color为该宠物定义,名称为”。

这称为半连接,因为SQL服务器可能在后台与Color进行连接,但结果集中不返回Color的数据。由于未返回Color个数据,因此无论为任何给定Pet定义的Color行的数量是多少,您都只会从petName获取一行。

答案 2 :(得分:1)

如果“另一行中每行有一行多行”,则会重复单行值。

所以这是正确的:

petName petType petName petColor
Unicorn Horse   Unicorn white
Unicorn Horse   Unicorn silver

SQL无法使用INNER JOIN生成此内容。

petName petType petName petColor
Unicorn Horse   Unicorn white
<   NULL   >   Unicorn silver

就这么简单。

答案 3 :(得分:0)

这是预期的。

您的查询正在加入每个表中的petName列,并返回匹配的结果。在这里,它在Color表中找到一个名为Unicorn Horse的Pet表中的颜色为white的匹配项,然后在Color表中找到名为Unicorn Horse的Pet表中的第二个匹配项颜色silver

答案 4 :(得分:0)

并不是MySQL在第二行填充空数据。

您的查询字面意思是“从PetName为马的两个表中提供所有内容。

就MySQL而言,它并不知道你希望宠物中的第一个独角兽行是白色的,然后有一个额外的独角兽与银不匹配。相反它说“我有这个独角兽有2个属性,白色和银色。根据我的第一张桌子,我知道所有的独角兽都是马。所以我有一匹白马独角兽和一匹银色的独角兽。”

就目的而言,您可以删除冗余数据。例如,如果每个企业都有1个地址但是有多个销售人员,则您不希望在每个销售人员上存储相同的地址,因为当需要进行更改时,您必须更新大量记录。

相反,你可以说“Testco在123大街上.Bob,John,Sally和Frank都是Testco的销售人员。”那么“鲍勃的地址是什么”这个问题的答案就是“123大街”,但是你看看Testco的记录是为了得到那个,而不是鲍勃的记录。

答案 5 :(得分:0)

你有一只独角兽宠物有两种颜色,所以两排。 如果你向Pet添加了另一行,其中包含独角兽的宠物名称和一种神秘生物,那么你就有四行。

如果您在考虑隐藏重复数据,那就是演示问题。每个人仍然是独角兽,你根本就没有展示,因为你已经拥有。唯一的方法是“知道”它与上面的相同。