Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 左联接返回的值超出预期值_Mysql_Sql - Fatal编程技术网

Mysql 左联接返回的值超出预期值

Mysql 左联接返回的值超出预期值,mysql,sql,Mysql,Sql,使用以下查询 select * from table1 left join table2 on table1.name = table2.name table1返回16行,table2返回35行 我原以为上面的查询会返回16行,因为左连接,但它返回35行右连接还返回35行 为什么会发生这种情况?如何让它返回16行?如果表1中某一行的外键被表2中的多行引用,LEFT JOIN可以返回表1中数据的多个副本 如果您希望它只返回16行,每个表1行一行,并且表2有一个随机数据集,那么您可以通过以下方式使

使用以下查询

select *
from table1
left join table2 on table1.name = table2.name
table1
返回16行,
table2
返回35行

我原以为上面的查询会返回16行,因为
左连接
,但它返回35行<代码>右连接还返回35行


为什么会发生这种情况?如何让它返回16行?

如果表1中某一行的外键被表2中的多行引用,LEFT JOIN可以返回表1中数据的多个副本

如果您希望它只返回16行,每个表1行一行,并且表2有一个随机数据集,那么您可以通过以下方式使用普通组:

select *
from table1
left join table2 on table1.name = table2.name
group by table1.name

groupby
根据字段聚合行,因此这将把所有table1重复项折叠成一行。通常,可以指定聚合函数来解释行应该如何折叠(例如,对于数字行,可以使用SUM()折叠它,这样一行就是总数)。如果只需要一个随机行,则不要指定任何聚合函数。默认情况下,MySQL只选择一行(请注意,这是MySQL特有的,大多数数据库在分组时都需要指定聚合)。它选择的方式在技术上不是“随机的”,但对你来说不一定是可预测的。我猜“random”实际上是指“任何行都可以”。

如果表中的name列不是唯一的,那么表2中可能有重复项

尝试运行:

select * from table2 where name not in (select name from table1);

如果没有返回结果,则名称列上的重复项是返回额外行的原因。

假设您有以下表格:

tbl1:
|Name |
-------
|Name1|
|Name2|

tbl2:
|Name |Value |
--------------
|Name1|Value1|
|Name1|Value2|
|Name3|Value1|
对于您的左侧连接,您将获得:

|tbl1.Name|tbl2.Name|Value |
----------------------------
|Name1    | Name1   |Value1|
|Name1    | Name1   |Value2|
|Name2    | NULL    | NULL |
所以,LEFT JOIN意味着将返回左(第一)表中的所有记录,而不管它们是否存在于右表中

对于您的问题,您需要指定一些特定字段,而不是使用“*”,并添加
分组依据tbl1.Name
——因此您的查询如下所示

select tbl1.Name, SOME_AGGREGATE_FUNCTION(tbl2.specific_field), ...
from table1
left join table2 on table1.name = table2.name
GROUP BY tbl1.Name

根据您的评论“表2中的随机行,只要表1中的名称与表2中的名称匹配”,您可以使用以下内容:

select table1.name, (select top 1 somecolumn from table2 where table2.name = table1.name)
from table1

请注意,TOP1不是mysql,而是用于SQL Server的。使用它的一种方法是使用SQL distinct的强大功能

select distinct tbl1.id, *
from table1 tbl1
left join table2 tbl2 on tbl2.name = tbl1.name

where
 ....................

请不要说我也在使用别名。

重复可能是原因。参见帖子中的示例

额外的行是否返回空值?如果tbl1中的所有名称与tbl2中的行之间存在链接,则查询将返回35行。我认为
table
table2
之间的关系是一对多的。是这样吗?@oshirowanen在这种情况下,您需要提供更多的条件,指定如何限制结果。由于有三行不同的数据集,您希望如何折叠它们?Mysql可以对它们进行分组并运行聚合函数,但您需要首先指定聚合的工作方式。表2中有一个随机行,只要表1中的名称与表2中的名称匹配。同意:OP需要向我们显示正在使用的源数据和所需的输出。@oshirowanen,我更新后解释了如何只获取16行,为每个table2关联选择一行。@BenLee感谢您提供的信息,他不知道MySQL的这种行为。@SergeyKudriavtsev,注意我刚刚澄清了细节。MySQL在默认情况下不会返回随机行,但在默认情况下会返回一行,并且不一定以可预测的方式返回。所以如果你只是“任何一行都可以”,你可以使用这个方法。如果您确实需要一个真正的随机行,那么这是一个更复杂的查询。MySQL使用
LIMIT
。还有,随机性在哪里?