I have the following query:
select
products.id,
products.description,
products.barcode,
getStock(products.id, 'Production') AS total_stock
from `products`
having total_stock > 0
order by products.description asc
Which is pretty straight forward. However, the results returned are incorrect. It’s currently returning 2 rows and if I remove the order by clause it returns 4000 rows.
select
products.id,
products.description,
products.barcode,
getStock(products.id, 'Production') AS total_stock
from `products`
having total_stock > 0
Applying a group by clause, like referred in enumerous topics such as Error with ORDER BY used with HAVING Clause, has no success, as the number of rows returned is, again, 2.
select
products.id,
products.description,
products.barcode,
getStock(products.id, 'Production') AS total_stock
from `products`
group by products.id, products.description, products.barcode
having total_stock > 0
order by products.description asc
What am I missing?
Edit 1: The getStock function
DELIMITER $$
CREATE FUNCTION getStock (productId INT, environment VARCHAR(255)) RETURNS INT(11)
BEGIN
DECLARE qty INT(11) DEFAULT 0;
SELECT SUM(pw.stock) INTO qty
FROM products_wholesalers AS pw
INNER JOIN subscriptions AS subscription ON subscription.id = pw.subscription_id
WHERE pw.product_id = productId
AND pw.active = true
AND subscription.type = 'Wholesaler'
AND subscription.active = true
AND subscription.environment = environment;
RETURN qty;
END $$
>Solution :
The issue is related to how SQL are processed, with ‘HAVING’ and ‘ORDER BY’ combination. Your query return 4000 rows because it’s not sorting the results by description so it returns all rows meet HAVING condition.
In SQL, HAVING clause filters results after grouping done by the GROUP BY clause and ORDER BY clause sorts rows in the result set befure it’s returned.
To solve, you can try to use a subquery
SELECT * FROM (
SELECT
products.id,
products.description,
products.barcode,
getStock(products.id, 'Production') AS total_stock
FROM `products`
) AS subquery
WHERE total_stock > 0
ORDER BY description ASC;