左连接查询返回重复项

时间:2013-08-03 14:08:46

标签: mysql sql left-join

我有添加剂表:

id   name
30   gro
31   micro
32   bloom
33   test

和stage_additives表:

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

这对我来说没有意义,因为结果中的每个项目都有3个,即使每个表中只有一个项目具有相同的ID /名称。

我也尝试过内连接,右连接但结果几乎完全相同,除了订单。

我想要的是所有id,来自添加剂的名称和来自stage_additives的剂量,否则为NULL(或更好的自定义值为0)

3 个答案:

答案 0 :(得分:8)

您错过了left join中的条件:

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在概念上在两个表之间执行cross join并且仅采用与on条件匹配的行(left join也保留所有第一个表中的行)。如果没有on条件,则连接将保留两个表中sa.stage_id = 195所有行的所有行对,这就是很多对。

编辑:

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

条件sa.stage_id = 195故意在on子句中。这可以确保left join实际上表现得像书面一样。如果条件移至where子句,则left join将变为inner join。来自additivestage_additive中不匹配的行将NULL的{​​{1}}值被过滤掉。由于sa.stage_id的明确使用,我必须假设left join的OP旨在将所有行保留在additive中。

答案 1 :(得分:1)

条款ON中的

应该是WHERE

中stage_id的表和条件之间的关系

答案 2 :(得分:0)

你可能想要像

这样的东西
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:http://sqlfiddle.com/#!2/fd607/4

在这种情况下,您可以使用LEFT JOIN代替INNER JOIN,因为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:http://sqlfiddle.com/#!2/fd607/8

但也许你真的想要一个LEFT JOIN

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:http://sqlfiddle.com/#!2/fd607/7