使用以下查询
select *
from table1
left join table2 on table1.name = table2.name
table1
返回16行,table2
返回35行。
由于left join
,我期望上面的查询返回16行,但它返回35行。 right join
也会返回35行
为什么会发生这种情况,如何让它返回16行?
答案 0 :(得分:12)
如果表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
GROUP BY
根据字段聚合行,因此这会将所有table1重复项折叠为一行。通常,您指定聚合函数来解释行应如何折叠(例如,对于数字行,您可以使用SUM()折叠它,因此一行将是总数)。如果您只想要一个随机行,请不要指定任何聚合函数。 MySQL默认只选择一行(请注意,这是特定于MySQL的,大多数数据库都要求您在分组时指定聚合)。它选择它的方式在技术上并不是“随机的”,但它不一定是你可预测的。我想通过“随机”你真的只是意味着“任何行都会做”。
答案 1 :(得分:4)
假设您有以下表格:
tbl1:
|Name |
-------
|Name1|
|Name2|
tbl2:
|Name |Value |
--------------
|Name1|Value1|
|Name1|Value2|
|Name3|Value1|
对于你的LEFT JOIN,你会得到:
|tbl1.Name|tbl2.Name|Value |
----------------------------
|Name1 | Name1 |Value1|
|Name1 | Name1 |Value2|
|Name2 | NULL | NULL |
因此,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
答案 2 :(得分:1)
使用它的一种方法是使用SQL distinct的强大功能。
select distinct tbl1.id, *
from table1 tbl1
left join table2 tbl2 on tbl2.name = tbl1.name
where
....................
请注意,我也在使用别名。
答案 3 :(得分:0)
如果表格中的名称列不是唯一的,那么您可能只是在table2上有重复项。
尝试跑步:
select * from table2 where name not in (select name from table1);
如果没有得到任何结果,那么名称列上的重复数据就是额外行返回的原因。
答案 4 :(得分:0)
重复可能是原因。请参阅帖子中的示例
https://alexpetralia.com/posts/2017/7/19/more-dangerous-subtleties-of-joins-in-sql
答案 5 :(得分:-1)
根据您的评论“table2中的随机行,只要table1中的名称与table2中的名称匹配”,您可以使用以下内容:
select table1.name, (select top 1 somecolumn from table2 where table2.name = table1.name)
from table1
请注意,top 1不是mysql,而是SQL Server