Ao usar GROUP BY, você pode usar expressões em sua lista de seleção somente se elas tiverem um único valor por grupo. Caso contrário, você obterá resultados de consulta ambíguos.
No seu caso, o MySQL acredita que
s.status
pode ter vários valores por grupo. Por exemplo, você está agrupando por p.products_id
mas s.status
é uma coluna em outra tabela specials
, talvez em um relacionamento um-para-muitos com a tabela products
. Portanto, pode haver várias linhas em specials
com o mesmo products_id
, mas valores diferentes para status
. Se for esse o caso, qual valor para status
a consulta deve usar? É ambíguo. Em seus dados, você pode limitar as linhas de forma que tenha apenas uma linha em
specials
para cada linha em products
. Mas o MySQL não pode fazer essa suposição. O MySQL 5.6 e anteriores permitem que você escreva essas consultas ambíguas, confiando que você sabe o que está fazendo. Mas o MySQL 5.7 permite uma aplicação mais rigorosa por padrão (isso pode ser menos rigoroso para se comportar como versões anteriores).
A correção é seguir esta regra:Cada coluna em sua lista de seleção deve se enquadrar em um dos três casos:
- A coluna está dentro de uma função agregada como COUNT(), SUM(), MIN, MAX(), AVERAGE() ou GROUP_CONCAT().
- A coluna é uma das colunas nomeadas no
GROUP BY
cláusula. - A coluna é funcionalmente dependente das colunas nomeadas no
GROUP BY
cláusula.
Para mais explicações, leia este excelente blog:Debunking GROUP BY myths
Sobre seu comentário, só posso dar um palpite porque você não postou suas definições de tabela.
Acho que
products_description
e manufacturers
são funcionalmente dependentes de products
, então não há problema em listá-los como estão na lista de seleção. Mas essa suposição pode não estar correta, não conheço seu esquema. De qualquer forma, o erro sobre
s.status
deve ser resolvido usando uma função agregada. Estou usando MAX()
como um exemplo. 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;
Eu também reescrevi suas junções da maneira correta. As junções no estilo vírgula devem ser evitadas.