【问题标题】:Mysql left/inner join combination not working as expectedMysql左/内连接组合没有按预期工作
【发布时间】:2012-03-15 09:14:40
【问题描述】:

我正在尝试列出订购数量的产品变体,但还要显示没有订购数量的产品变体。所以我认为这就像选择产品并对每个产品的订单进行左连接一样简单,其中订单是当前版本。

所以我期望像这样的操作顺序:

SELECT p.product_id, SUM(po.quantity) 
FROM `products` p 
LEFT JOIN `product_orders` po ON p.product_id=po.product_id 
LEFT JOIN `orders` o ON o.order_id=po.order_id AND o.is_current='1'

但这也得到了 is_current 不是 1 的数量 然后我想,好吧,我可以在左连接之后做一个内连接,而不是像这样:

SELECT p.product_id, SUM(po.quantity) 
FROM `products` p 
LEFT JOIN `product_orders` po ON p.product_id=po.product_id 
INNER JOIN `orders` o ON o.order_id=po.order_id AND o.is_current='1'

但是尚未列出尚未订购的产品。我希望它们显示为 SUM(quantity) 为 NULL。 谁能看到我的逻辑哪里出错了? 谢谢! 斯科特

【问题讨论】:

    标签: mysql


    【解决方案1】:

    虽然 Kaj 的回答是正确的,但它不一定是理想的,因为 MySQL 在使用派生表(子选择)时往往会跳过索引的使用。至少,这是我的理解。如果您将连接放在括号内,您可以继续使用您使用 JOINS 的方法:

    SELECT p.product_id, SUM(po.quantity) 
    FROM `products` p 
    LEFT JOIN (`product_orders` po
      INNER JOIN `orders` o ON o.order_id=po.order_id AND o.is_current='1')
    ON p.product_id=po.product_id;
    

    请记住,LEFT JOIN 的 ON 子句需要放在括号之后。我希望这会有所帮助!

    【讨论】:

    • 对不起,我不经常使用stackoverflow,也不知道如何将代码放到自己的部分中。
    • 我有时会忽略您在索引和子选择方面提出的出色观点。很好的解释。
    • 谢谢!我尽我所能……哈。
    • 对于其他寻求参考的人,请参阅Nested Join Optimization 上的 MySQL 文档
    • 较新版本的 MySQL 会自动为派生表创建索引。 (这比没有索引要好,但通常不如重新编写查询。)
    【解决方案2】:

    如果唯一计数的产品订单是当前的产品订单,那么您需要在对它进行左连接之前找到该子集。否则,如果您进行左连接,您将获得所有或仅获得您发现的那些订购的。

    所以类似下面的东西应该可以工作:

    select p.productid, sum(po.quantity)  
    from products p  
    left outer join (select po.productid, po.quantity  
                           from productorders po  
                           inner join orders o on o.orderid = po.orderid and o.iscurrent = 1) po on po.productid = p.productid  
    group by p.productid
    

    【讨论】:

    • 有道理,我试试……一秒
    • 完美,效果很好!!正是需要的。非常感谢!
    • 没问题。你走在正确的轨道上;只是需要一个额外的步骤
    【解决方案3】:

    尝试按您的产品 ID 分组:

    SELECT p.product_id, SUM(po.quantity) 
    FROM `products` p 
    LEFT JOIN `product_orders` po ON p.product_id=po.product_id 
    INNER JOIN `orders` o ON o.order_id=po.order_id AND o.is_current='1'
    GROUP BY p.product_id
    

    【讨论】:

    • 感谢您的回复,仍然只列出至少订购数量为一个的产品(因此出现在 product_orders 表中)
    • INNER JOIN改回LEFT JOIN是否有效?
    • 是的,查询然后工作,但我也得到了 is_current!='1' 的所有数量(所以相同订单的旧版本)
    猜你喜欢
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 2012-03-31
    • 2016-11-28
    相关资源
    最近更新 更多