MySQL:为什么我必须指定在该列加入表时使用哪些表列?

时间:2017-03-10 01:48:24

标签: mysql

如果我有两张桌子:

+-----------------+
+ people          |
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | Joe  |  42 |
|  2 | Sue  |  30 |
+----+------+-----+

+-------------------+
+ employees         |
+----+------+-------+
| id | dept | hired |
+----+------+-------+
|  1 | HR   |  2015 |
|  2 | Dev  |  2013 |
+----+------+-------+

我查询的是这样的人:

SELECT * FROM employees JOIN people ON employees.id=people.id WHERE id=2;

为什么会抛出错误?我知道id并不是唯一的,但我强迫它是 common ,因为它必须由JOIN共享。我也知道我可以通过询问SELECT *,people.id AS id FROM...来绕过这一点,但这是一个理论问题,而不是寻找解决方案。

这只是MySQL没有得到足够开发的情况吗?或者是否有正当理由抛出此错误?

3 个答案:

答案 0 :(得分:1)

您在想的是将连接的表视为一个,并且在该视图中有一个id列。 MySQL可以通过使用子选择和自然连接来容纳该视图。

SELECT * FROM (SELECT * FROM employees NATURAL JOIN people) AS t2 WHERE id=2;

这会折叠所有公共列,同时也将它们用作连接的条件。返回的列将按公共列的顺序排列,其余列将构成第一个表,其余列将来自第二个表。在公共列中,如果有多个,它们的顺序将与它们在第一个表中的顺序相同,即使它们在第二个表中具有不同的顺序。

这允许您在脑海中查看数据时从MySQL中实现逻辑。

警告,如果有多个公共列,结果可能不是您所期望的。然后,连接将强制每列匹配,然后才将它们视为“匹配”。如果列组合形成一个键,那么这是预期的行为。但是,如果恰好有两个列具有相同的名称,但不同的用法不属于该键,则最终可能会出现一个空集。

答案 1 :(得分:0)

由于您使用的是WHERE,因此不仅仅是您在FROM之后放置的表格的过滤器。它将过滤这些表的结果

你想做的事情甚至对人类来说都是模糊的。查询可能比您使用的示例更复杂。根据你的想法,阅读调试可能会更难。

同样在WHERE之后按表格选择将为您提供更大的灵活性。例如,您可以使用WHERE employees.id=people.id

如何在PHP之类的内容中使用这些类型的查询?您正在使用SELECT * FROM,您希望通过PHP内的$ row [' id']获得什么?

这种选择有利于更清晰的查询和更大的灵活性,并解决了机器和人类的歧义。

答案 2 :(得分:0)

最简单的答案是,当查询多个表时,MySQL期望field子句中的table.field时,只提供WHERE引用就像尝试登录系统一样没有提供您的用户名,只提供您的密码。抱歉,当您要登录时,您必须告诉系统您提供的密码。Key + Datum = result. Null + Datum = Error.

更深入一点,MySQL不会在JOIN语句 UNTIL THE QUERY FINISHES 中定义的两个表之间建立连接。 WHERE子句按顺序处理,以确保表在连接时进行过滤。如果您想要搜索特定ID#的两个表,那么您需要为其添加语法。类似的东西:

`SELECT * FROM employees FULL JOIN people ON employees.id=people.id WHERE (employee.id = 2 OR people.id = 2)`

这是不同的,当一个或另一个表在公共表中没有匹配时,FULL JOIN仍然有效,它仍然会添加到结果中,缺少的条目的空列为NULL。

在各种类型的JOIN中有很多,包括this SO post,而even older SO posthttp://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_RestoreFromSnapshot.html的骗局,可以更详细地解释这一点。

TL:DR - 如果你使用一个表,MySQL知道在哪里看。当您使用多个表时,MySQL很容易混淆,需要确定您正在使用哪个表。这就是为什么它会向你抛出错误。修复很简单,您只需要在WHERE子句中向查询中添加两个内容,例如:

'SELECT * FROM employees LEFT JOIN people ON employees.id=people.id WHERE employee.id = 2'

将LEFT添加到JOIN为服务器提供了额外的指令,说明组合资产和将表名添加到列名称的方式将告诉MySQL需要查看哪个表。