Когато използвате GROUP BY, можете да използвате изрази във вашия списък за избор само ако имат една стойност за група. В противен случай получавате двусмислени резултати от заявката.
Във вашия случай MySQL смята, че s.status
може да има няколко стойности на група. Например, вие групирате по p.products_id
но s.status
е колона в друга таблица specials
, може би във връзка един към много с таблица products
. Така че може да има няколко реда в specials
със същия products_id
, но различни стойности за status
. Ако случаят е такъв, коя стойност за status
трябва ли заявката да използва? Това е двусмислено.
В данните си може да се случи да ограничите редовете така, че да имате само един ред в specials
за всеки ред в products
. Но MySQL не може да направи това предположение.
MySQL 5.6 и по-стари ви позволяват да пишете толкова двусмислени заявки, като се доверявате, че знаете какво правите. Но MySQL 5.7 позволява по-стриктно прилагане по подразбиране (това може да бъде направено по-малко строго, за да се държи като по-ранни версии).
Поправката е да следвате това правило:Всяка колона във вашия списък за избор трябва да попада в един от трите случая:
- Колоната е вътре в агрегатна функция като COUNT(), SUM(), MIN, MAX(), AVERAGE() или GROUP_CONCAT().
- Колоната е една от колоните, наречени в
GROUP BY
клауза. - Колоната е функционално зависима от колоната(ите), наименувани в
GROUP BY
клауза.
За повече обяснения прочетете този отличен блог:Развенчаване на ГРУПА ПО митове
Относно вашия коментар мога само да направя предположение, защото не сте публикували дефинициите на вашата таблица.
Предполагам, че products_description
и manufacturers
са функционално зависими от products
, така че е добре да ги изброите, както е в списъка за избор. Но това предположение може да не е правилно, не знам вашата схема.
Както и да е, грешката за s.status
трябва да се разреши чрез използване на агрегатна функция. Използвам MAX()
като пример.
SELECT p.*,
pd.*,
m.*,
MAX(IF(s.status, s.specials_new_products_price, NULL))
AS specials_new_products_price,
MAX(IF(s.status, s.specials_new_products_price, p.products_price))
AS final_price
FROM products p
LEFT OUTER JOIN specials s ON p.products_id = s.products_id
INNER JOIN manufacturers m ON p.manufacturers_id = m.manufacturers_id
INNER JOIN products_description pd ON p.products_id = pd.products_id
INNER JOIN products_to_categories p2c ON p.products_id = p2c.products_id
INNER JOIN categories c ON p2c.categories_id = c.categories_id
WHERE p.products_view = 1
AND p.products_status = 1
AND p.products_archive = 0
AND c.virtual_categories = 0
AND pd.language_id = 1
GROUP BY p.products_id;
Също така пренаписах вашите присъединявания по правилния начин. Съединенията в стил запетая трябва да се избягват.