Question

I have a query which shows sold and unsold products.

below is the query which is working correctly.

 SELECT p.product_id, 
    p.product_brand_id, 
    p.product_model_id, 
    p.product_subcategory_id,
    p.product_retail_price, 
    p.product_wholesale_price, 
    SUM(IFNULL(ps.product_quantity,0)) AS product_quantity_sold,
    SUM(IFNULL(ps.product_total_price,0)) AS total_price_sold, 
    pb.brand_name, 
    pm.model_name, 
    psub.subcategory_name
 FROM product p
 LEFT JOIN product_sold ps ON p.product_id = ps.product_id
 LEFT JOIN sales s ON ps.product_sales_id = s.sales_id
 JOIN product_brand pb ON pb.brand_id = p.product_brand_id
 JOIN product_model pm ON pm.model_id = p.product_model_id
 JOIN product_subcategory psub ON psub.subcategory_id = p.product_subcategory_id
 WHERE p.product_brand_id = $brand_id AND p.product_model_id = $model_id
   AND ( s.sales_id IS NULL
   OR ( s.sales_approved = '1' 
      AND s.sales_approved_time > '$start_timestamp'  
      AND s.sales_approved_time < '$end_timestamp'
      )
   )
   AND pb.brand_name NOT LIKE 'X%'
 GROUP BY p.product_id 
 ORDER BY product_quantity_sold DESC, pb.brand_name ASC, pm.model_name ASC

but onced added having to filter the list to only show

product that have stock or products that have been sold only, with this query below:

 SELECT p.product_id, 
    p.product_brand_id, 
    p.product_model_id, 
    p.product_subcategory_id,
    p.product_retail_price, 
    p.product_wholesale_price, 
    SUM(IFNULL(ps.product_quantity,0)) AS product_quantity_sold,
    SUM(IFNULL(ps.product_total_price,0)) AS total_price_sold, 
    SUM(IFNULL(pq.product_quantity,0)) AS total_stock, 
    pb.brand_name, 
    pm.model_name, 
    psub.subcategory_name
 FROM product p
 LEFT JOIN product_sold ps ON p.product_id = ps.product_id
 LEFT JOIN sales s ON ps.product_sales_id = s.sales_id
 LEFT JOIN product_stock pq ON p.product_id = pq.product_id
 JOIN product_brand pb ON pb.brand_id = p.product_brand_id
 JOIN product_model pm ON pm.model_id = p.product_model_id
 JOIN product_subcategory psub ON psub.subcategory_id = p.product_subcategory_id
 WHERE p.product_brand_id = $brand_id AND p.product_model_id = $model_id
   AND ( s.sales_id IS NULL
   OR ( s.sales_approved = '1' 
      AND s.sales_approved_time > '$start_timestamp'  
      AND s.sales_approved_time < '$end_timestamp'
      )
   )
   AND pb.brand_name NOT LIKE 'X%'
 GROUP BY p.product_id 
 HAVING total_stock > 0 OR product_quantity_sold > 0
 ORDER BY product_quantity_sold DESC, pb.brand_name ASC, pm.model_name ASC

Its kinda weird because im getting different results on each product for the variable below

product_quantity_sold

everything else in the result stays the same.

Was it helpful?

Solution

This has nothing to do with HAVING.

Your second query joins with the product_stock table, whereas the first query does not. Thus, every pre-aggregation record is repeated for each related stock entry.

product_id = 577, for example, appears in product_stock 8 times, so its value for product_quantity_sold is 8 times greater in the second query (184) than in the first (23).

OTHER TIPS

Your group by clause is defective - you need to list all the non-aggregate columns:

...
group by p.product_id, 
    p.product_brand_id, 
    p.product_model_id, 
    p.product_subcategory_id,
    p.product_retail_price, 
    p.product_wholesale_price, 
    pb.brand_name, 
    pm.model_name, 
    psub.subcategory_name 

in other database I know, not doing this would cause an error, but in mysql it's allowed but has special non-sql standard meaning of returning a single random row for each unique combination of values listed in the group by clause from the matching rows, not an aggregation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top