【问题标题】:Query with several consecutive LEFT JOIN - unexpected results具有多个连续 LEFT JOIN 的查询 - 意外结果
【发布时间】:2013-08-23 13:29:41
【问题描述】:

我的目标是填充几个子类(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    

我不知道为什么。尝试了不同的东西,但这就是我想出的。有人有想法吗?

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

【问题讨论】:

    标签: mysql join left-join


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢,我编辑了我的问题以考虑您的回答,并使其更清晰。
    • 您的查询是否会返回多行(由于所有连接)而您只查看第一行?
    • 不,实际上恰恰相反。我希望它返回负载和行负载。在我的示例中,它只返回一个,但在不同的 WHERE 条件下,它会返回很多。我没有找到正确的行,并且查询工作正常。导致问题的原因是行没有完全填充。
    • 好的,谢谢 Gordon,这正是您所说的。首先没有给予足够的关注,因为我认为我做了需要做的事情,但实际上并没有那么多:)
    【解决方案2】:

    这似乎是您需要将 where 移动到连接本身的经典案例,这样它就不会阻塞其他所有内容:

    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;
    

    【讨论】:

      【解决方案3】:
      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 ;
      

      使用它它必须工作正常。如果您有额外的 where 查询,您可以添加它。

      【讨论】:

        猜你喜欢
        • 2016-09-10
        • 1970-01-01
        • 1970-01-01
        • 2016-08-29
        • 1970-01-01
        • 2021-01-28
        • 1970-01-01
        • 2015-02-24
        • 1970-01-01
        相关资源
        最近更新 更多