使用以下查询
select *
from table1
left join table2 on table1.name = table2.name
Run Code Online (Sandbox Code Playgroud)
table1返回16行并table2返回35行.
我期待上面的查询返回16行因为left join,但它返回35行. right join也返回35行
为什么会发生这种情况,如何让它返回16行?
Ben*_*Lee 13
如果表1中的行的外键被table2中的多行引用,则LEFT JOIN可以从table1返回数据的多个副本.
如果您希望它只返回16行,每个表1行一个,并且为表2提供随机数据集,则只能使用普通的GROUP BY:
select *
from table1
left join table2 on table1.name = table2.name
group by table1.name
Run Code Online (Sandbox Code Playgroud)
GROUP BY基于字段聚合行,因此这会将所有table1重复项折叠为一行.通常,您指定聚合函数来解释行应如何折叠(例如,对于数字行,您可以使用SUM()折叠它,因此一行将是总数).如果您只想要一个随机行,请不要指定任何聚合函数.MySQL默认只选择一行(请注意,这是特定于MySQL的,大多数数据库都要求您在分组时指定聚合).它选择它的方式在技术上并不是"随机的",但它不一定是你可预测的.我想通过"随机"你真的只是意味着"任何行都会做".
假设您有以下表格:
tbl1:
|Name |
-------
|Name1|
|Name2|
tbl2:
|Name |Value |
--------------
|Name1|Value1|
|Name1|Value2|
|Name3|Value1|
Run Code Online (Sandbox Code Playgroud)
对于您的LEFT JOIN,您将获得:
|tbl1.Name|tbl2.Name|Value |
----------------------------
|Name1 | Name1 |Value1|
|Name1 | Name1 |Value2|
|Name2 | NULL | NULL |
Run Code Online (Sandbox Code Playgroud)
因此,LEFT JOIN意味着将返回LEFT(第一)表中的所有记录,而不管它们是否存在于右表中。
对于您的问题,您需要指定一些特定的字段而不是使用“ *”并添加GROUP BY 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
Run Code Online (Sandbox Code Playgroud)