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子句中,而不是在何处是正确的,因为我需要添加剂表中的所有行,而不考虑阶段