Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Erro do MySQL:a lista SELECT não está na cláusula GROUP BY


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.