2011-02-25 118 views
1

我需要在8个表中做一个SELECT,但结果不是我所期望的。多表MySQL查询返回的结果太多

丑陋的代码:

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项,是不对的。

Explainig上面的代码:

我的表equipment是我主表,在那里我有cod_equip field(主场我所有从表)。

我所有的从表我已经给了一个叫equip_前缀(是在总 7个从表)

现在我需要一个SELECTJOIN所有8台。

添加更多:

我期待9行,但它获取63行,我需要表现出这样的事情:表设备(只有1行)和其他表尊重号吧拥有。

例如equip_adaptador插入具有相同cod_equip两次,然后我需要表现出来..

该查询是一样的,如果我做逐一查询,看看我有什么与equipment.cod_equip ='EC726026316A0'

就是这样!

在此先感谢人!

+0

是什么让你觉得这是不对的?你有多少行? – Dismissile 2011-02-25 20:48:06

+0

预期结果是什么?编辑:Aww打败了我25秒 – Shaded 2011-02-25 20:48:30

+0

@Dismissile我期待9行,但它取得63行,我需要显示这样的东西:设备(只有1行)和其他表的尊重号码拥有。例如equip_adaptador是两次插入相同的cod_equip,然后我需要显示它.. – B4NZ41 2011-02-25 21:00:35

回答

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 

这是为了避免产生“重复”子行的一种方式。

+0

非常感谢您的解释,我明白发生了什么,现在我将使用多选(运行单独的查询)来展示我需要的东西,我认为是唯一的方法。您的回复已被接受。再次感谢。 – B4NZ41 2011-02-26 00:54:09

5

你的ON子句应该对你加入的表有约束。目前他们没有。因此,例如,您将在equip_adaptador.cod_equip = equipment.cod_equip的所有情况下加入equip_fonte。这个陈述的真相与equip_fonte中发生的事情没有任何关系。

+0

好眼睛。甚至没有注意到:) – Dismissile 2011-02-25 20:49:51

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' 
+0

我发布了错误的sql代码,很抱歉,但是您修复了表名,谢谢。你的代码返回给我113行,仍然错了我正在寻找的结果.. – B4NZ41 2011-02-25 21:02:53

+0

@Fernando哥斯达黎加:你做一个左外连接...这将返回设备表中的所有行..是你寻找正常的连接? – Mulki 2011-02-25 21:16:21

+0

LEFT OUTER JOIN返回给我的结果与LEFT JOIN相同。 只有连接返回给我一个错误。 – B4NZ41 2011-02-25 21:27:46