У меня есть следующий запрос:
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
Это довольно просто. Однако полученные результаты неверны. В настоящее время он возвращает 2 строки, и если я удалю предложение order by
, он вернет 4000 строк.
select
products.id,
products.description,
products.barcode,
getStock(products.id, 'Production') AS total_stock
from `products`
having total_stock > 0
Применение предложения group by
, о котором говорится в многочисленных темах, таких как Ошибка с ORDER BY, используемым с предложением HAVING, не имеет успеха, поскольку количество возвращаемых строк снова равно 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
Что мне не хватает?
Редактировать 1: функция getStock
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 $$
Проверьте планы EXPLAIN
на наличие различий. Возможно, там что-то есть.
Единственная разница в EXPLAIN
— это отображение информации «Использование сортировки файлов» на вкладке Extra
, в зависимости от того, применяю ли я ORDER BY
или нет. Да, могу поделиться функцией getStock
, пост обновлен.
@damjad не знаю, поможет ли это, но я только что тестировал на другой машине, и запрос (с предложением ORDER BY
) работает отлично. Может ли это быть связано с версией MySQL? На машине с ошибками версия MySQL — 5.7.44, а машина, на которой он работал — 10.4.27.
5.7.44 — это версия MySQL, а 10.4.27 — это версия MariaDB. Это разные базы данных с множеством несовместимых функций. MariaDB отделилась от MySQL в 2010 году, но с тех пор оба продукта продолжали меняться независимо, и к настоящему моменту вам не следует считать MariaDB «типом MySQL».
@BillKarwin Ты прав, это действительно заметно 10.4.27-MariaDB
. Он поставляется с Xampp.
Кроме того: версия 5.7 больше никем не поддерживается, вплоть до отсутствия даже обновлений безопасности. Лучше всего отказаться от системы 5.7.
Проблема связана с тем, как обрабатывается SQL с комбинацией HAVING и ORDER BY. Ваш запрос возвращает 4000 строк, поскольку он не сортирует результаты по описанию и возвращает все строки, соответствующие условию HAVING.
В SQL предложение HAVING фильтрует результаты после группировки, выполненной предложением GROUP BY, а предложение ORDER BY сортирует строки в наборе результатов перед его возвратом.
Для решения можно попробовать использовать подзапрос
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;
Протестировано и работает, но теперь у меня может возникнуть более серьезная проблема. Мне придется перевести это в проект Laravel и разобраться с отношениями. Дай мне минутку.
Что делает
getStock
? Можете поделиться реализацией?