MySQL在多个左连接行的位置

时间:2017-10-18 08:50:23

标签: mysql left-join where

我有一个MySQL左连接查询,它返回表A中的1行和表B中的多行。我需要在这些行上有多个WHERE子句,并且只有在所有B行匹配时才返回。

我有:

SELECT 

mage_sales_order.entity_id

FROM mage_sales_order 

LEFT JOIN mage_sales_order_item 
ON mage_sales_order.entity_id = mage_sales_order_item.order_id 

WHERE 

 mage_sales_order_item.sku NOT LIKE '1-%' 
 AND mage_sales_order_item.sku LIKE '2-%' 

 ## Group order IDs together 
 GROUP BY entity_id

但是,这将返回任何包含SKU以" 2开始的项目的订单 - "即使它有一个以" 1 - "开头的项目。我想要它,以便订购仅以" 2开始的物品 - "归还。

例如:

应该退回:

  • 订单1(mage_sales_order)
    • 2-sampleA-sku(mage_sales_order_item)
    • 2-sampleB-sku(mage_sales_order_item)

不应该退回:

  • 订单1(mage_sales_order)
    • 1-sample-sku(mage_sales_order_item)
    • 2-sampleA-sku(mage_sales_order_item)
    • 2-sampleB-sku(mage_sales_order_item)

我认为这已经被问到了,但是试图搜索它是很困难的。

3 个答案:

答案 0 :(得分:1)

您可以添加另一个子查询来排除这些行,例如:

SELECT mage_sales_order.entity_id
FROM mage_sales_order 
LEFT JOIN mage_sales_order_item 
ON mage_sales_order.entity_id = mage_sales_order_item.order_id 
WHERE mage_sales_order_item.sku LIKE '2-%' 
AND mage_sales_order_item.order_id NOT IN (
    SELECT order_id FROM mage_sales_order_item WHERE sku LIKE '1-%'
)
GROUP BY entity_id;

答案 1 :(得分:0)

我认为您需要将WHERE子句中的逻辑移到HAVING子句:

SELECT
    t1.entity_id
FROM mage_sales_order t1
LEFT JOIN mage_sales_order_item t2
    ON t1.entity_id = t2.order_id
GROUP BY
    t1.entity_id
HAVING
    SUM(CASE WHEN t2.sku NOT LIKE '2-%' THEN 1 ELSE 0 END) = 0;

当前WHERE子句的逻辑问题是此逻辑应用于各个记录。说SKU应该以{{1​​}}开头并且不以2-开头是没有意义的,因为前一个条件已经保证了后者。但是,在对实体进行聚合的情况下,逻辑似乎确实有意义。

答案 2 :(得分:0)

您只需将WHERE子句中的条件移动到JOIN

即可
SELECT mage_sales_order.entity_id
FROM mage_sales_order 
LEFT JOIN mage_sales_order_item 
ON 
   mage_sales_order.entity_id = mage_sales_order_item.order_id 
   AND mage_sales_order_item.sku NOT LIKE '1-%' 
   AND mage_sales_order_item.sku LIKE '2-%' 
WHERE mage_sales_order_item.order_id IS NOT NULL
GROUP BY entity_id