Mysql
 sql >> Database >  >> RDS >> Mysql

Errore MySQL:l'elenco SELECT non è nella clausola GROUP BY

Quando si utilizza GROUP BY, è possibile utilizzare le espressioni nell'elenco di selezione solo se hanno un unico valore per gruppo. Altrimenti ottieni risultati di query ambigui.

Nel tuo caso, MySQL ritiene che s.status potrebbe avere più valori per gruppo. Ad esempio, stai raggruppando per p.products_id ma s.status è una colonna in un'altra tabella specials , forse in una relazione uno-a-molti con la tabella products . Quindi potrebbero esserci più righe in specials con lo stesso products_id , ma valori diversi per status . In tal caso, quale valore per status la query dovrebbe usare? È ambiguo.

Nei tuoi dati, potresti limitare le righe in modo tale da avere solo una riga in specials per ogni riga in products . Ma MySQL non può fare questa ipotesi.

MySQL 5.6 e versioni precedenti ti consentono di scrivere query così ambigue, confidando che tu sappia cosa stai facendo. Ma MySQL 5.7 consente un'applicazione più rigorosa per impostazione predefinita (questo può essere reso meno rigoroso per comportarsi come le versioni precedenti).

La soluzione è seguire questa regola:ogni colonna nell'elenco di selezione deve rientrare in uno dei tre casi seguenti:

  • La colonna si trova all'interno di una funzione aggregata come COUNT(), SUM(), MIN, MAX(), AVERAGE() o GROUP_CONCAT().
  • La colonna è una delle colonne denominate in GROUP BY clausola.
  • La colonna dipende funzionalmente dalle colonne citate in GROUP BY clausola.

Per ulteriori spiegazioni leggi questo eccellente blog:Debunking GROUP BY miti

Riguardo al tuo commento, posso solo fare un'ipotesi perché non hai pubblicato le definizioni delle tue tabelle.

Immagino che products_description e manufacturers sono funzionalmente dipendenti da products , quindi va bene elencarli così come sono nell'elenco di selezione. Ma questa ipotesi potrebbe non essere corretta, non conosco il tuo schema.

Ad ogni modo, l'errore su s.status dovrebbe essere risolto utilizzando una funzione di aggregazione. Sto usando MAX() come esempio.

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;

Ho anche riscritto i tuoi join nel modo corretto. I join in stile virgola dovrebbero essere evitati.