多表MySQL查询返回太多结果

时间:2011-02-25 20:46:40

标签: mysql join left-join

我需要在8个表中进行SELECT,但结果并不是我所期望的。

丑陋的代码:

SELECT equipment.*
FROM equipment
LEFT JOIN equip_adaptador  a ON (a.cod_equip = equipment.cod_equip)
LEFT JOIN equip_antena aa ON (aa.cod_equip = equipment.cod_equip)
LEFT JOIN equip_cable c ON (c.cod_equip = equipment.cod_equip)
LEFT JOIN equip_conector cc ON (cc.cod_equip = equipment.cod_equip)
LEFT JOIN equip_fonte f ON (f.cod_equip = equipment.cod_equip)
LEFT JOIN equip_router r ON (r.cod_equip = equipment.cod_equip)
LEFT JOIN equip_suporte s ON (s.cod_equip = equipment.cod_equip)
WHERE equipment.cod_equip = 'EC726026316A0'

结果是63项,不对。

解释上面的代码:

我的表equipment是我的主表,我有cod_equip field(我所有从属表的主域)。

我所有的奴隶表我给了一个名为equip_的前缀(总共有7个奴隶表

现在我需要SELECTJOIN所有8个表。

添加更多内容:

我期待9行,但它取了63行,我需要显示这样的东西:表设备(只有1行)和其他表所拥有的尊重数量。

例如 equip_adaptador 两次使用相同的 cod_equip 插入,然后我需要显示它..

此查询与我逐个查询一样查看我的 equipment.cod_equip ='EC726026316A0'

就这么做!

先谢谢大家!

3 个答案:

答案 0 :(得分:5)

您的ON子句应该对您要加入的表有约束。目前他们没有。因此,例如,您将在equip_adaptador.cod_equip = equipment.cod_equip的所有情况下加入equip_fonte。而且该陈述的真实性与equip_fonte中发生的事情无关。

答案 1 :(得分:2)

发生的事情是从子表返回的每一行都与从其他子表返回的每一行匹配。

您可以按预期返回一个父行。

但是,如果其中一个子表有七(7)个匹配行,而另一个子表有九(9)个匹配行,则返回7 * 9 = 63行。

根据SQL规范,这是预期的结果集。

这是一个测试案例,演示了正在发生的事情:

CREATE TABLE t (id INT);
CREATE TABLE c1 (id INT, t_id INT);
CREATE TABLE c2 (id INT, t_id INT);

INSERT INTO t VALUES (1);
INSERT INTO c1 VALUES (11,1),(12,1);
INSERT INTO c2 VALUES (21,1),(22,1);

SELECT t.id, c1.id AS c1, c2.id AS c2
FROM t
JOIN c1 ON (t.id = c1.t_id)
JOIN c2 ON (t.id = c2.t_id)

id  c1   c2
--  ---  ---
1   11   21
1   12   21
1   11   22
1   12   22

请注意,c1中的行重复一次,对于c2中的每一行。同样适用于来自c2的行。

这正是我们期望的结果集。

如果我们不想要子行的交叉连接(笛卡尔积),我们可以运行单独的查询:

SELECT t.id, c1.id AS c1
FROM t
JOIN c1 ON (t.id = c1.t_id) 

SELECT t.id, c2.id AS c2
FROM t
JOIN c2 ON (t.id = c2.t_id)

id  c1
--  ---
1   11
1   12

id  c2
--  ---
1   21
1   22

这是避免产生"重复"的一种方法。子行。

答案 2 :(得分:1)

也许在连接条件下你的表名错了...... 试试这个

SELECT equipment.*
    FROM equipment
    LEFT JOIN equip_adaptador  a ON (a.cod_equip = equipment.cod_equip)
    LEFT JOIN equip_antena aa ON (aa.cod_equip = equipment.cod_equip)
    LEFT JOIN equip_cable c ON (c.cod_equip = equipment.cod_equip)
    LEFT JOIN equip_conector cc ON (cc.cod_equip = equipment.cod_equip)
    LEFT JOIN equip_fonte f ON (f.cod_equip = equipment.cod_equip)
    LEFT JOIN equip_router r ON (r.cod_equip = equipment.cod_equip)
    LEFT JOIN equip_suporte s ON (s.cod_equip = equipment.cod_equip)
    WHERE equipment.cod_equip = 'EC726026316A0'