查询连续几次LEFT JOIN - 意外结果

时间:2013-08-23 13:29:42

标签: mysql join left-join

我的目标是填充多个子类(B,C,D,E,F ...)的几个对象,所有这些对象都扩展了一个父类,即A。所有这些都在一个唯一的大查询中。

我们说我有几个反映类结构的表,包括这3个:

Table A /* the parent class */
id       type        created
--------------------------------
392      B           1377084886

Table B /* one of the child classes */
id       myfield     myotherfield     anotherone    oneagain
-------------------------------------------------------------
392      234         'foo'            'bar'         3

Table G /* not part of the structure, just here for the query to check a field */
myfield      fieldtocheck       evenmorefields
------------------------------------------------
234          'myvalue1'         'foobar'

现在:

/* This (the query I want): */
SELECT
    a.*,
    b.*,
    c.*,
    d.*,
    e.*,
    f.*
    FROM A a
    LEFT JOIN B b ON a.id = b.id
    LEFT JOIN C c ON a.id = c.id
    LEFT JOIN D d ON a.id = d.id
    LEFT JOIN E e ON a.id = e.id
    LEFT JOIN F f ON a.id = f.id
    LEFT JOIN G g_b ON b.myfield = g_b.myfield
    LEFT JOIN G g_c ON c.myfield = g_c.myfield
    WHERE g_b.fieldtocheck IN (myvalue1);

/* Returns this (what I don't want): */
id->392
type->B
created->1377084886
myfield->NULL /* why NULL? */
myotherfield->NULL /* why NULL? */
anotherone->NULL /* why NULL? */
oneagain->3 /* why, whereas other fields from B are NULL, is this one correctly filled? */

鉴于:

/* This (the query I don't want): */
SELECT
    a.*,
    b.*
    FROM A a
    LEFT JOIN B b ON a.id = b.id
    LEFT JOIN G g_b ON b.myfield = g_b.myfield
    WHERE g_b.fieldtocheck IN (myvalue1);

/* Returns this (what I want): */
id->392
type->B
created->1377084886
myfield->234
myotherfield->'foo'
anotherone->'bar'
oneagain->3    

我不知道为什么。试过不同的事情,但这就是我想出来的。有人有想法吗?

编辑:澄清了这篇文章并使其更直接。

3 个答案:

答案 0 :(得分:2)

我认为您面临的问题是查询中名称的冲突。也就是说,有多个具有相同名称的列,MySQL会选择其中一个作为结果。

您需要将每个表的列名别名别名为其他名称,例如a_createdb_created等。

答案 1 :(得分:1)

这似乎是一个典型的案例,你需要将你的位置移动到连接本身,这样它就不会阻止其他一切:

SELECT
    A.*,
    B.*,
    C.*,
    D.*,
    E.*,
    F.*,
    FROM A
    LEFT JOIN B ON A.id = B.id
    LEFT JOIN C ON A.id = C.id
    LEFT JOIN D ON A.id = D.id
    LEFT JOIN E ON A.id = E.id
    LEFT JOIN F ON A.id = F.id
    LEFT JOIN G ON B.myfield = G.myfield and G.anotherfield IN (myvalue1)
    LEFT JOIN H ON C.myfield = H.myfield;

答案 2 :(得分:0)

SELECT a.id, a.type, a.created, b.myfield, b.myotherfield FROM `A` AS a INNER JOIN `B` AS b ON a.id = b.id ;

使用它必须正常工作。如果您有其他位置查询,则可以添加它。