SELECT DISTINCT
получает все различные комбинации всех выбранных полей в вашем запросе, а не только первое поле.
Теперь вы можете решить эту проблему, используя GROUP BY для выбора толькоотдельные значения id_product, в частности, такие как:
SELECT p.`id_product`, p.*, product_shop.*, pl.* , m.`name` AS manufacturer_name, x.`id_feature` , x.`id_feature_value` , s.`name` AS supplier_name
FROM `ps_product` p
INNER JOIN ps_product_shop product_shop
ON (product_shop.id_product = p.id_product AND product_shop.id_shop = 1)
LEFT JOIN `ps_product_attribute` y ON (y.`id_product` = p.`id_product`)
LEFT JOIN `ps_product_attribute_combination` ac ON (y.`id_product_attribute` = ac.`id_product_attribute`)
LEFT JOIN `ps_product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.id_shop = 1 )
LEFT JOIN `ps_manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
LEFT JOIN `ps_feature_product` x ON (x.`id_product` = p.`id_product`)
LEFT JOIN `ps_supplier` s ON (s.`id_supplier` = p.`id_supplier`)
LEFT JOIN `ps_category_product` c ON (c.`id_product` = p.`id_product`)
WHERE pl.`id_lang` = 1 AND c.`id_category` = 18 AND p.`price` between 0 and 1000
AND product_shop.`visibility` IN ("both", "catalog") AND product_shop.`active` = 1
GROUP BY p.`id_product`
ORDER BY p.`id_product` ASC LIMIT 1,4
Однако теперь проблема состоит в том, что в вашем запросе есть несколько различных значений всех других полей, из которых вы выбираете, и нет детерминированного способа выбора из них.,Несмотря на то, что id_product уникален в своей таблице, он не уникален в наборе результатов, потому что, по крайней мере, в одном из ваших JOIN имеется отношение один ко многим, что означает, что есть несколько строк, соответствующих условиям JOIN.
В более старых версиях MySQL он просто выберет первое найденное значение в этом случае, но на SQL Server он фактически выдаст ошибку и сообщит, что оставшиеся поля должны быть упомянуты в предложении GROUP BY, или онидолжны быть агрегированы.Итак, у вас есть несколько способов, с помощью которых вы можете перейти отсюда:
- Вы используете старую версию MySQL и вам не особо важно, какие значения возвращаются для остальных полей,так что оставьте запрос, как я написал, и используйте его.Я не рекомендовал бы это, поскольку это неопределенное поведение, поэтому в теории это могло измениться по прихоти MySQL.Все возвращаемые значения будут взяты из одной и той же строки результатов.
- Добавьте агрегатные функции, такие как MIN () или MAX (), к остальным полям в предложении выбора.Это уменьшит возможные значения для полей до одного, но вы, вероятно, в конечном итоге получите смесь значений из разных строк.
- Удалите любые СОЕДИНЕНИЯ со многими один из вашего запроса, так что вы только когда-либополучить одну строку назад в наборе результатов для каждого отдельного id_product.Затем извлеките оставшиеся данные, которые вам нужны, в отдельном запросе.
Могут быть и другие альтернативные решения, но это во многом зависит от того, какие значения вы хотите вернуть для остальных строк и какую СУБД вы используетеИспользуем.Например, на SQL Server вы могли бы потенциально использовать PARTITION BY для детерминистского выбора первой строки для каждого отдельного id_product.