简体   繁体   中英

SQL query left join where clause

This is my situation.

I have 3 tables

Orders
 - id  status deleted

Order Lines
 - related_id related_model quantity

Products
 - id  code  price  price_purchase

I want to create a list with all products . The amount of times they are purchased and a sum of the gross margin (price - price_purchase). It must only use orders lines with the related model set to 'products' . And secondly it must only pick orders with the status set to 'paid, processing, sent, ready_for_pickup or picked_up' and with the order not deleted.

So this would be the result I want:

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

This is the SQL query I have so far:

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

It returns the correct data. But not all problems. That is my problem. I a lot of different methods like sub queries and other methods but can't seem to solve the problem. I know the problem is my LEFT join, but don't know a solution to my problem.

I'm using MySQL Workbench.

Any help is welcome.

Your joins are wrong. You need to identify the order lines to consider separately from and prior to forming the LEFT JOIN with the product details. An inline view could help:

  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

Move outer table conditions from WHERE to ON, otherwise the OUTER JOIN works like a regular 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

Is p.id the whole primary key for that table? If not, you need to find out how to treat p.code. (Either list in GROUP BY, or use as argument to aggregate function.)

Another try:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM