SQL查询左连接where子句

时间:2015-03-26 13:34:57

标签: mysql sql join

这是我的情况。

我有3张桌子

Orders
 - id  status deleted

Order Lines
 - related_id related_model quantity

Products
 - id  code  price  price_purchase

我想创建一个包含all products的列表。 amount of times they are purchasedsum of the gross margin(价格 - price_purchase)。它必须只使用related model set to 'products'的订单行。其次,它必须只选择status set to 'paid, processing, sent, ready_for_pickup or picked_up'和订单not deleted.

的订单

所以这就是我想要的结果:

id | code  | purchases | value
-------------------------------
1  | code1 | 7         | 57,05
2  | code2 | 122       | 254,98
3  | code3 | 0         | 0,00

这是我到目前为止的SQL查询:

SELECT p.id, p.code, IFNULL(SUM(sol.quantity) , 0) as purcahses,     
sum((p.price - p.price_purchase) * quantity) as value
FROM products p
LEFT JOIN shop_orders_lines sol ON sol.related_id = p.id 
AND sol.related_model = 'products'
LEFT JOIN shop_orders so ON so.id = sol.order_id 

WHERE so.status IN ('paid', 'processing', 'sent', 'ready_for_pickup', 'picked_up')
AND so.deleted = 0  
GROUP BY p.id

返回正确的数据。但不是所有的问题。那是我的问题。我有很多不同的方法,比如子查询和其他方法,但似乎无法解决问题。我知道问题是我的LEFT加入,但不知道我的问题的解决方案。

我正在使用MySQL Workbench。

欢迎任何帮助。

2 个答案:

答案 0 :(得分:2)

你的联盟是错的。您需要在与产品详细信息形成LEFT JOIN之前和之前分别确定订单行。内联视图可以提供帮助:

  SELECT
    p.id,
    p.code,
    IFNULL(SUM(ordered_item.quantity) , 0) as purchases ,     
    sum((p.price - p.price_purchase) * ordered_item.quantity) as value
  FROM
   products p
   LEFT JOIN (
      SELECT
        sol.related_id AS related_id,
        sol.quantity AS quantity
      FROM
        shop_orders_lines sol
        INNER JOIN shop_orders so
          ON so.id = sol.order_id
      WHERE
        so.status IN ('paid', 'processing', 'sent', 'ready_for_pickup', 'picked_up')
          AND so.deleted = 0
          AND sol.related_model = 'products'  
    ) ordered_item
      ON ordered_item.related_id = p.id
GROUP BY p.id

答案 1 :(得分:1)

将外表条件从WHERE移到ON,否则OUTER JOIN就像常规的INNER JOIN一样工作:

SELECT p.id, p.code, IFNULL(SUM(sol.quantity) , 0) as purcahses,     
sum((p.price - p.price_purchase) * quantity) as value
FROM products p
LEFT JOIN shop_orders_lines sol ON sol.related_id = p.id 
AND sol.related_model = 'products'
LEFT JOIN shop_orders so ON so.id = sol.order_id AND
so.status IN ('paid', 'processing', 'sent', 'ready_for_pickup', 'picked_up')
AND so.deleted = 0
GROUP BY p.id

p.id是该表的整个主键吗?如果没有,你需要找出如何对待p.code。 (在GROUP BY中列出,或者用作聚合函数的参数。)

另一次尝试:

SELECT p.id, p.code, IFNULL(SUM(sol.quantity) , 0) as purcahses,     
sum((p.price - p.price_purchase) * quantity) as value
FROM products p
JOIN shop_orders_lines sol ON sol.related_id = p.id 
AND sol.related_model = 'products'
WHERE EXISTS (select 1 from shop_orders so
              where so.id = sol.order_id
                AND so.status IN ('paid', 'processing', 'sent', 'ready_for_pickup', 'picked_up')
                AND so.deleted = 0)
GROUP BY p.id