Mysql 左连接查询返回重复项

Mysql 左连接查询返回重复项,mysql,sql,left-join,Mysql,Sql,Left Join,我有一张表: id name 30 gro 31 micro 32 bloom 33 test stage_id additive_id dose 195 30 2 195 31 3 195 32 1 和阶段添加剂表: id name 30 gro 31 micro 32 bloom 33 test stage_id additive_id

我有一张表:

id   name
30   gro
31   micro
32   bloom
33   test
stage_id  additive_id   dose
195       30            2
195       31            3
195       32            1
和阶段添加剂表:

id   name
30   gro
31   micro
32   bloom
33   test
stage_id  additive_id   dose
195       30            2
195       31            3
195       32            1
Mysql查询:

SELECT a.id,
       a.name,
       sa.dose
FROM   additives a
LEFT JOIN stage_additives sa
ON     sa.stage_id = 195
结果是:

id name  dose
32 Bloom 2
32 Bloom 3
32 Bloom 1
30 Gro 2
30 Gro 3
30 Gro 1
31 Micro 2
31 Micro 3
31 Micro 1
33 test 2
33 test 3
33 test 1
这对我来说没有意义,因为即使每个表中只有一个具有相同id/名称的项,结果中每个项也有3个

我也尝试了内部连接,右连接,但结果几乎相同,除了顺序


我想要的是所有id、来自添加剂的名称和来自阶段添加剂的剂量,如果它存在,则为空(或者更好的是自定义值为0)

中的
子句
应该是
中阶段id的表和条件之间的关系,其中
您缺少
左连接中的条件

SELECT a.id,
       a.name,
       sa.dose
FROM   additives a
LEFT JOIN stage_additives sa
ON     a.id = sa.additive_id and sa.stage_id = 195;
请记住,
join
在概念上是在两个表之间进行
交叉连接
,并且只获取符合
on
条件的行(
左连接也保留第一个表中的所有行)。通过不使用
on
条件,联接将保留两个表中的所有行对,其中
sa.stage_id=195
——这是大量的行对

编辑:

(响应将条件
sa.stage_id=195
移动到
where
子句中。)


条件
sa.stage_id=195
故意出现在
on
子句中。这确保了
左连接实际的行为与写入的一样。如果将条件移动到
where
子句,则
左连接将变成
内部连接。在
stage\u additive
中不匹配的
additive
中的行对于
sa.stage\u id
将具有
NULL
值并被过滤掉。我必须假设,OP用于
左连接
以保持所有行在
加法
中,因为显式使用了
左连接

,您可能希望

SELECT a.id,
       a.name,
       sa.dose
FROM   additives a
LEFT JOIN stage_additives sa 
          ON sa.additive_id = a.id
WHERE  sa.stage_id = 195
SQLFiddle:

在这种情况下,您可以使用
内部联接来代替
左联接
,因为
WHERE
子句是基于联接的成功

SELECT a.id,
       a.name,
       sa.dose
FROM   additives a
INNER JOIN stage_additives sa 
           ON sa.additive_id = a.id AND sa.stage_id = 195
SQLFiddle:

但也许你真的想要一个
左连接

SELECT a.id,
       a.name,
       sa.dose
FROM   additives a
LEFT JOIN stage_additives sa
          ON sa.additive_id = a.id AND sa.stage_id = 195
这将返回第四行:

33  test    (null)

SQLFiddle:

就是这样!我仍然很困惑,为什么我得到的是3件相同的物品,而不是2件或4件?@DominicM。对于测试数据,我希望您得到4个输出行,在
additive
中每行一个。如果您将
stage\u id
上的条件移动到
where
子句,则将得到3行。
JOIN
基本上是表的叉积。假设表
a
包含(1)、(2)和表
b
包含(3)、(4)、(5)
a连接b
将生成6行结果:(1,3)、(1,4)、(1,5)、(2,3)(2,4)和(2,5)。这是左表值的3倍,右表值的2倍。从概念上讲,
ON
WHERE
子句只用于从该交叉产品中删除不需要的结果。Gordon Linoff说条件应该在ON子句中,而不是在何处是正确的,因为我需要添加剂表中的所有行,而不考虑阶段