代码之家  ›  专栏  ›  技术社区  ›  BenKoshy Mayinx

为什么Mysql的左连接条件没有得到遵守?

  •  0
  • BenKoshy Mayinx  · 技术社区  · 5 年前

    查询返回意外结果:为什么?

    +----------------+
    | Field          |
    +----------------+
    | orderNumber    |
    | customerNumber |
    +----------------+
    

    OrderDetails表:

    +-----------------+
    | Field           |
    +-----------------+
    | orderNumber     |
    | productCode     |
    +-----------------+
    

    考虑下面的查询:

    SELECT 
        o.orderNumber, 
        o.customerNumber, 
        d.orderNumber,
        d.productCode
    FROM
        orders o
    LEFT JOIN orderdetails d 
        ON ((o.orderNumber = d.orderNumber) AND (o.orderNumber = 10123)) ;
    

    结果如下:

    Results

    我希望看到订单号仅为10123的行

    为什么我们会看到其他订单号?我本以为连接的条件(即。 o.orderNumber = 10123 )应该排除其他行吗?这对我来说真是太离奇了,有着意想不到的结果:任何关于发生了什么的澄清都将不胜感激。

    更新-将条件添加到 WHERE 条款

    我可以补充说,这是真的 o、 订单号=10123 加入WHERE条款,这将解决问题,但我担心它应该 还在工作吗 当包含在ON条款中时,这是意料之中的,不是吗?为什么?因为如果o.orderNumber不是10123,条件将返回false,因此应该从结果集中排除?

    更新:可复制示例:

    以下是mysql数据库: https://sp.mysqltutorial.org/wp-content/uploads/2018/03/mysqlsampledatabase.zip

    这是一个在线版本,您可以在其中键入命令: https://www.mysqltutorial.org/tryit/

    非常感谢。

    4 回复  |  直到 5 年前
        1
  •  3
  •   GMB    5 年前

    如果要筛选给定订单号的结果集,请在 WHERE 条款:

    SELECT ...
    FROM orders o
    LEFT JOIN orderdetails d ON d.orderNumber = o.orderNumber
    WHERE o.orderNumber = 10123;
    

    这将带来给定数量的所有订单,以及相应的订单详细信息。如果没有订单详细信息,您仍然可以获得给定编号的订单行。如果该数字没有顺序,则结果集为空。

        2
  •  1
  •   AlexKD    5 年前

    LEFT JOIN子句允许您从多个表中查询数据。它返回左表中的所有行和右表中的匹配行。如果在右表中找不到匹配行,则使用NULL( https://www.sqlservertutorial.net/sql-server-basics/sql-server-left-join/ )因此,从“开启”条件中确实没有什么可期待的。对于LEFT JOIN,它们仅位于第二张桌子附近。我建议作者更好地了解各种连接

        3
  •  1
  •   Gordon Linoff    5 年前

    如果你想要 JOIN 要筛选第二个表中不匹配的结果,请使用 内部的 加入:

    SELECT o.orderNumber, o.customerNumber, d.orderNumber, d.productCode
    FROM orders o JOIN
         orderdetails d 
         ON o.orderNumber = d.orderNumber 
    WHERE o.orderNumber = 10123;
    

    如果要包含不匹配的行,则使用外部联接。

    过滤 orderNumber 可以在任何一个 ON 条款或 WHERE 子句——它们相当于 内部的 参加然而,我认为将这种过滤放在数据库中的一个表上更“传统” 哪里 条款

        4
  •  1
  •   Julien B.    5 年前

    简而言之,您正在请求 orders 桌子您的join子句将从 orderdetails 只有当你有匹配的 orderNumber 当 订单号 是 10123 ,但您仍然可以从 命令 .

    如果你想从 命令 只有当 订单号 是 10123 ,你应该在 命令 桌子通常的方法是使用 WHERE 条款

    当使用 LEFT JOIN 您将从联接表中获得匹配的记录(基于条件),但仍将从联接表中获得所有记录 左边 桌子

    这应该行得通。

    SELECT 
        o.orderNumber, 
        o.customerNumber, 
        d.orderNumber,
        d.productCode
    FROM
        orders o
    LEFT JOIN orderdetails d 
        ON (o.orderNumber = d.orderNumber) 
    WHERE o.orderNumber = 10123;